Причината, поради която това ви се струва странно, е, че мислите за увеличението на брояча като част от операцията за вмъкване и следователно „НЕ ПРАВИ НИЩО“ би трябвало да означава „не увеличавайте нищо“. Представяте си това:
- Проверете стойностите за вмъкване спрямо ограничение
- Ако се открие дубликат, прекратете
- Последователност на нарастване
- Вмъкване на данни
Но всъщност увеличението трябва да се случи преди да се направи опит за вмъкване . A SERIAL
колоната в Postgres е внедрена като DEFAULT
който изпълнява nextval()
функция върху обвързана SEQUENCE
. Преди СУБД да може да направи нещо с данните, тя трябва да има пълен набор от колони, така че редът на операциите е следният:
- Разрешаване на стойностите по подразбиране, включително увеличаване на последователността
- Проверете стойностите за вмъкване спрямо ограничение
- Ако се открие дубликат, прекратете
- Вмъкване на данни
Това може да се види интуитивно, ако дублираният ключ е в самото поле за автоматично увеличение:
CREATE TABLE foo ( id SERIAL NOT NULL PRIMARY KEY, bar text );
-- Insert row 1
INSERT INTO foo ( bar ) VALUES ( 'test' );
-- Reset the sequence
SELECT setval(pg_get_serial_sequence('foo', 'id'), 0, true);
-- Attempt to insert row 1 again
INSERT INTO foo ( bar ) VALUES ( 'test 2' )
ON CONFLICT (id) DO NOTHING;
Ясно е, че това не може да знае дали има конфликт без увеличаване на последователността, така че "не прави нищо" трябва да дойде след това увеличение.