我正在创建一个Web应用程序,该应用程序将使用权限,角色和FK来限制数据访问,并将所有用户信息存储在一个数据库中。此应用程序中的一个表跟踪由每个用户创建的工单(即,工单表的用户表具有FK)。
我想确保每个用户都有自己的不间断的“工作订单ID”序列,这些序列在计划工作订单时分配。也就是说,如果用户1创建了他的第一个工作指令,它将分配给它#1,但是,如果用户2创建了他的第五个工作指令,它将分配给它#5。
工作单表具有UUID主键,因此每个记录都是可区分的,并且用户FK具有非空约束。
根据我到目前为止的研究,似乎Postgres序列可能是我最好的答案。我需要为每个用户创建一个序列,并将其合并到触发器中,以使用下一个适当的ID标记工作订单记录。但是,这似乎需要大量的性能,为每个用户创建一个新序列将面临一系列挑战。
第二种方法可能是创建第二个表,该表跟踪每个用户的最新序列,对其进行查询,递增并更新工作单表和编号跟踪表。但是,在这种情况下,我认为如果两个用户恰好同时转换记录,则很容易受到竞争条件的影响。
我不确定解决问题的最佳方法是什么。还有另一种方法可以提供更好的性能吗?
序列对您不起作用,因为它们在设计上不是事务性的:如果具有生成编号的插入失败,即使在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;
这是原子的,不受种族条件的影响。只要确保您在同一数据库事务中运行该更新和插入,那么它们将要么成功要么都失败并且被撤消。
这将把每个用户的插入序列化到工作单表中,但是无间隙的序列总是是性能问题。