一张表中基于所有者/外键的Postgres唯一序列

时间:2020-01-14 17:25:58

标签: postgresql

我正在创建一个Web应用程序,该应用程序将使用权限,角色和FK限制数据访问,将所有用户信息存储在一个数据库中。此应用程序中的表之一跟踪由每个用户创建的工单(即工单表的用户表有FK)。

我要确保每个用户都有自己的不间断“工作订单ID”序列,这些序列在计划工作订单时分配。也就是说,如果用户1创建了他的第一个工作订单,它将分配给它#1,但是,如果用户2创建了他的第五个工作订单,它将分配给它#5。

工作单表具有UUID主键,因此每个记录都是可区分的,并且用户FK具有非空约束。

根据我到目前为止的研究,似乎Postgres序列可能是我最好的答案。我需要为每个用户创建一个序列,并将其合并到触发器中,以使用下一个适当的ID标记工作订单记录。但是,这似乎需要大量的性能,并且为每个用户创建一个新序列将面临一系列挑战。

第二种方法可能是创建第二个表,该表跟踪每个用户的最新序列,对其进行查询,递增并更新工作单表和号码跟踪表。但是,在这种情况下,如果两个用户恰好同时转换记录,我认为这很容易受到竞争条件的影响。

我不确定解决问题的最佳方法是什么。还有另一种方法可以提供更好的性能吗?

1 个答案:

答案 0 :(得分:0)

序列对您不起作用,因为它们在设计上不是事务性的:如果具有生成编号的插入失败,即使在beginning之后,该编号也会被消耗。

您应该创建第二个表

ROLLBACK

然后您将得到下一个号码

CREATE TABLE counters (
   user_id bigint PRIMARY KEY REFERENCES users ON DELETE CASCADE,
   work_order_id bigint NOT NULL DEFAULT 0
);

这是原子的,并且不受比赛条件的影响。只要确保您在同一数据库事务中运行该更新和插入,那么它们将要么成功要么都失败并且被撤消。

这会将每个用户的插入序列化到工作单表中,但是无间隙序列总是 一个性能问题。