是存储最新事件数据的最佳方式



我们使用一个基于事件的系统,其中使用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(); 

看演示。

相关内容

  • 没有找到相关文章

最新更新