POSTGRES-防止与ON CONFLICT的连续增加什么都不做



此问题的重复

假设我有以下桌子上的东西。我希望表中有唯一的名称,这样就不会有重复的名称插入事物的过程不需要检查是否已经存在具有此名称的事物

CREATE TABLE things(
id SMALLSERIAL PRIMARY KEY,
name varchar UNIQUE
);

当我插入这样的值时,它就起作用了。如果"桌子"已经在东西里了,它就不会被插入。

INSERT INTO things (name)
VALUES ('desk')
ON CONFLICT DO NOTHING;

唯一的问题是在冲突中什么也不做并不是什么都不做。它仍然递增id字段的序列。

如果这种情况发生得太频繁,id序列最终对于字段类型来说会变得太大。

有没有办法防止这种情况发生?

使用insert ... on conflict,无法阻止serial在冲突时自动递增。Postgres(就像其他数据库一样(不保证连续序列,正如文档中所解释的:

因为smallserialserialbigserial是使用序列来实现的;孔";或列中出现的值序列中的间隙,即使从未删除过任何行。从序列中分配的值仍然是"0";用完了";即使包含该值的行从未成功插入表列中。例如,如果插入事务回滚,则可能会发生这种情况。

如果您正在运行大量最终发生冲突的insert,则限制出血的一种方法是将语法更改为not exists:

insert into things (name)
select name
from (values ('desk')) v(name)
where not exists (select 1 from things t1 where t1.name = v.name)

请注意,这仍然不能保证序列是连续的(请参阅文档中的以上引用(。

最新更新