我们使用一个基于事件的系统,其中使用postgres数据库来存储事件审计。目前,我们使用postgres MATERIALIZED VIEW来存储任何事件的最新条目。对于任何修改数据的事件,我们更新主事件审计表并刷新MATERIALIZED VIEW,但这非常耗时。我们使用下面的python代码来刷新视图,但它只是删除旧视图并重新创建它,这非常耗时
await connection_pool.execute(
"REFRESH MATERIALIZED VIEW CONCURRENTLY events_current"
)
我想这不是正确的方式来处理,我的方法是创建一个新的表,并保持一个事件的最新数据。请让我知道这是否可以,或者是否有更好的方法。
如果需要进一步的资料,请告诉我。
物化视图不是一个糟糕的解决方案,但前提是您可以将其视为"时间点";(工作日开始,或过去3小时内,…)。在这个时候,这不是一个好的解决方案。要求。你的答案似乎是后者。
最好的选择是创建一个获取最新数据的视图。如果由于审计事件的大小,这是不可行的,那么需要寻找其他地方。我不喜欢创建一个包含最新数据的表。这将是复制数据,而复制的数据不可避免地会有所不同。但是这里有一个小改动:创建一个只包含事件id和event_audit日志id的表,只维护最后一个审计id。如果没有完整的表定义(ddl),我只能展示一个框架设置,但是您应该能理解。
create table event_last_audits(
event_id integer
, ea_id integer
, constraint last_event_audits_pk primary key (event_id)
, constraint last_event_audits_2fk
foreign key (ea_id)
references event_audits(ea_id)
);
然后可以在同一个触发器中同时维护event_audit和event_last_audit。比如:create or replace function audit_events()
returns trigger
language plpgsql
as $$
begin
with audit_rec( event_id, ea_id) as
( insert into event_audits(event_id, dml_action,old_status)
select new.event_id
, tg_op
, case when tg_op='INSERT'
then null
else old.status
end
returning event_id, ea_id
)
insert into event_last_audits(event_id, ea_id)
select event_id, ea_id
from audit_rec
on conflict (event_id)
do update
set ea_id = excluded.ea_id;
return new;
end; $$;
create trigger audit_events_aiur
after insert or update on events
for each row
execute function audit_events();
看演示。