我有一个系统,可以通过网络获取信息并将该信息放入 postgres 数据库中。信息只有一种“种类”,因此只有一张表。让我们像这样建立这个表的模型:
item: string
comment: jsonb
timestamp: datetime
Run Code Online (Sandbox Code Playgroud)
有很多项目,时间戳是由单独的系统生成的,然后再到达具有多个服务器的 Web 前端。我需要做的是保证插入到数据库中的给定item值的每条记录都比最后一条记录更新。如果它较旧,则不应将其添加到数据库中。
因此,为了澄清起见,假设有三个消息,如下所示:
Message 1:
{time: 1,
item: "A"
}
Message 2:
{time: 3,
item: "A"
}
Message 3:
{time: 2,
item: "b"
}
Run Code Online (Sandbox Code Playgroud)
如果消息按顺序到达1-2-3,则所有三个消息都会放入数据库中,因为消息 3 与消息 1 或 2 所针对的项目不同,因此不会进行比较。
如果消息按顺序到达,2-1-3则消息 1 不会放入数据库中,因为消息 2 是 item 的更新消息A。
我想使用数据库进行此检查,以避免不同服务器之间的竞争条件。
我一直在阅读 PostgreSQL 文档,看起来我无法通过约束或排除来做到这一点。如何让数据库在插入记录之前进行顺序检查?
假设你的桌子看起来像这样......
create table messages (
item text not null,
comment jsonb,
created_at timestamp not null
);
Run Code Online (Sandbox Code Playgroud)
您可以使用触发器来执行此操作。
create or replace function check_only_newer_messages_for_item() returns trigger as $foo$
declare max_created_at_for_item timestamp;
begin
max_created_at_for_item := (
select coalesce(max(created_at), '-infinity'::timestamp)
from messages
where item = new.item
);
if max_created_at_for_item >= new.created_at then
raise exception 'out of order message';
end if;
return new;
end;
$foo$ language plpgsql;
create trigger only_newer_messages_for_item
before insert on messages
for each row execute function check_only_newer_messages_for_item();
test=# insert into messages (item, created_at) values ('a', '2019-01-01');
INSERT 0 1
test=# insert into messages (item, created_at) values ('a', '2019-01-01');
ERROR: out of order message
CONTEXT: PL/pgSQL function check_only_newer_messages_for_item() line 10 at RAISE
test=# insert into messages (item, created_at) values ('b', '2018-01-01');
INSERT 0 1
test=# insert into messages (item, created_at) values ('b', '2018-01-02');
INSERT 0 1
test=# insert into messages (item, created_at) values ('b', '2018-01-01');
ERROR: out of order message
CONTEXT: PL/pgSQL function check_only_newer_messages_for_item() line 10 at RAISE
Run Code Online (Sandbox Code Playgroud)
item和上的综合索引created_at将有助于实现良好的效果。
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |