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

问题描述 投票:0回答:1

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

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

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

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

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

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

postgresql
1个回答
0
投票

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

您应该创建第二个表

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

然后您将得到下一个号码

UPDATE counters
SET work_order_id = work_order_id + 1
RETURNING work_order_id;

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

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

© www.soinside.com 2019 - 2024. All rights reserved.