PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

serial w postgresie jest zwiększany mimo że dodałem na konflikcie nic nie rób

Powodem, dla którego wydaje ci się to dziwne, jest to, że myślisz o zwiększaniu licznika jako części operacji wstawiania, a zatem „NIC NIC” powinno oznaczać „nie zwiększaj niczego”. Wyobrażasz sobie to:

  1. Sprawdź wartości do wstawienia względem ograniczenia
  2. Jeśli wykryto duplikat, przerwij
  3. Sekwencja przyrostu
  4. Wstaw dane

Ale w rzeczywistości przyrost musi nastąpić przed próbą wstawienia . SERIAL kolumna w Postgresie jest zaimplementowana jako DEFAULT który wykonuje nextval() funkcja na powiązanej SEQUENCE . Zanim DBMS będzie mógł cokolwiek zrobić z danymi, musi mieć kompletny zestaw kolumn, więc kolejność operacji jest następująca:

  1. Rozwiąż wartości domyślne, w tym inkrementację sekwencji
  2. Sprawdź wartości do wstawienia względem ograniczenia
  3. Jeśli wykryto duplikat, przerwij
  4. Wstaw dane

Można to intuicyjnie zobaczyć, jeśli zduplikowany klucz znajduje się w samym polu autoinkrementacji:

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;

Oczywiście nie można stwierdzić, czy istnieje konflikt bez zwiększania sekwencji, więc „nic nie rób” musi nastąpić po ten przyrost.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zapętlaj wymiar tablicy w plpgsql

  2. Czy jest operator postgresu NAJBLIŻSZEGO?

  3. Jak dodać warunkowy unikalny indeks w PostgreSQL

  4. Python Postgres psycopg2 ThreadedConnectionPool wyczerpany

  5. Szybki sposób na sprawdzenie liczby wierszy tabeli w PostgreSQL