POSTGRES - prevent serial incrementation with ON CONFLICT DO NOTHING [duplicate]

偶尔善良 提交于 2021-01-27 19:07:47

问题


duplicate of this question

Say I have the following table things. I want unique names in the table so there are no duplicates. The process that inserts a thing shouldn't need to check if a thing with this name is already there.

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

When I insert values like this it works. If 'desk' is already in things it won't be inserted.

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

Tho only problem is ON CONFLICT DO NOTHING does not really do nothing. It still increments the sequence for the id field.

If this happens too often the id sequence eventually gets too big for the field type.

Is there a way to prevent this from happening?


回答1:


Using insert ... on conflict, you can't prevent the serial to auto-increment on conflicts. Postgres (just like other databases) does not guarantees that serials are sequential, as explained in the documentation:

Because smallserial, serial and bigserial are implemented using sequences, there may be "holes" or gaps in the sequence of values which appears in the column, even if no rows are ever deleted. A value allocated from the sequence is still "used up" even if a row containing that value is never successfully inserted into the table column. This may happen, for example, if the inserting transaction rolls back.

If you are running a lots of insert that end up in conflict, one way to limit the bleading would be to change the syntax to 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)

Note that this still does not guarantee that serials will be sequential (refer to the above quote from the documentation).



来源:https://stackoverflow.com/questions/63720340/postgres-prevent-serial-incrementation-with-on-conflict-do-nothing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!