我如何在 PostgreSQL 中定义一个列,使得每个值都必须在一个序列中,而不是使用 type 时得到的序列,serial
而是一个不能插入值 2 的序列,除非列中已经存在值 1?
3 回答
我在这里写了一个使用 PL/PgSQL 实现无间隙序列的详细示例。
一般的想法是您想要一个表来存储序列值,并且您使用SELECT ... FOR UPDATE
后跟UPDATE
- 或简写UPDATE ... RETURNING
- 从中获取值,同时锁定行直到您的事务提交或回滚。
从理论上讲,您可以使用像这样工作的约束。(但它在实践中不起作用。)
- 计算行数。
- 评估
max(column) - min(column) + 1
。 - 比较结果。
您可能必须在创建 CHECK 约束之前插入一行。如果没有,max(column) 将返回 NULL。一排,
- 计算行数 (1)。
- 评估
max(column) - min(column) + 1
。(1 - 1 + 1 = 1) - 比较结果。(1 = 1)
有 10 行。.
- 计算行数 (10)。
- 评估
max(column) - min(column) + 1
。(10 - 1 + 1 = 10) - 比较结果。(10 = 10)
序列是否从 1 开始并不重要;如果存在间隙,这种检查方式将始终显示间隙。如果您需要保证无间隙序列从 1 开始,您可以将其添加到 CHECK 约束中。
据我所知,没有任何方法可以使用任何当前的 dbms 以声明方式执行此操作。为此,您需要对CREATE ASSERTION
. (但我可能是错的。)在 PostgreSQL 中,我认为您对此的唯一尝试涉及多个 AFTER 触发器中的过程代码。
我只有一张需要无缝的桌子。这是一个日历表。我们每晚运行一次查询来进行这些计算,它让我知道我是否有差距。
你写一个on insert tigger
或一个check constraint
。但是,这仍然允许之后删除“1”并且“2”保留在表中,您可能也必须解决这个问题。