Alasan mengapa ini terasa aneh bagi Anda adalah karena Anda memikirkan kenaikan pada penghitung sebagai bagian dari operasi penyisipan, dan oleh karena itu "DO NOTHING" seharusnya berarti "jangan menambah apa pun". Anda sedang membayangkan ini:
- Periksa nilai yang akan disisipkan terhadap batasan
- Jika duplikat terdeteksi, batalkan
- Urutan kenaikan
- Sisipkan data
Namun pada kenyataannya, kenaikan harus terjadi sebelum penyisipan dicoba . Sebuah SERIAL
kolom di Postgres diimplementasikan sebagai DEFAULT
yang mengeksekusi nextval()
berfungsi pada SEQUENCE
yang terikat . Sebelum DBMS dapat melakukan apapun dengan data, DBMS harus memiliki satu set kolom yang lengkap, sehingga urutan operasinya seperti ini:
- Menyelesaikan nilai default, termasuk menambah urutan
- Periksa nilai yang akan disisipkan terhadap batasan
- Jika duplikat terdeteksi, batalkan
- Sisipkan data
Ini dapat dilihat secara intuitif jika kunci duplikat ada di bidang peningkatan otomatis itu sendiri:
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;
Jelas, ini tidak dapat mengetahui apakah ada konflik tanpa menambah urutan, jadi "tidak melakukan apa-apa" harus muncul setelah kenaikan itu.