sql >> Databáze >  >> RDS >> PostgreSQL

seriál v postgresu se zvyšuje, i když jsem přidal na konfliktu nedělat nic

Důvod, proč se vám to zdá divné, je ten, že uvažujete o zvýšení na počítadle jako o součásti operace vkládání, a proto by „NEDĚLAT NIC“ mělo znamenat „nic nezvyšovat“. Představujete si toto:

  1. Zkontrolujte hodnoty, které chcete vložit proti omezení
  2. Pokud je detekován duplikát, přerušte jej
  3. Posloupnost přírůstků
  4. Vložte data

Ale ve skutečnosti musí ke zvýšení dojít před pokusem o vložení . SERIAL sloupec v Postgresu je implementován jako DEFAULT který provede nextval() funkce na vázané SEQUENCE . Než bude DBMS moci s daty cokoli dělat, musí mít kompletní sadu sloupců, takže pořadí operací je toto:

  1. Vyřešte výchozí hodnoty, včetně zvýšení sekvence
  2. Zkontrolujte hodnoty, které chcete vložit proti omezení
  3. Pokud je detekován duplikát, přerušte jej
  4. Vložte data

To lze intuitivně vidět, pokud je duplicitní klíč v samotném poli automatického přírůstku:

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;

Je zřejmé, že toto nemůže bez zvýšení sekvence zjistit, zda došlo ke konfliktu, takže „nedělat nic“ musí přijít po tento přírůstek.



  1. SQLiteDiskIOException s kódem chyby 10:chyba vstupu/výstupu disku

  2. Osvědčené postupy při škálování databází:Část druhá

  3. Složitý dotaz Postgres

  4. Je použití mysql_insert_id bezpečné?