PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

la série dans postgres est augmentée même si j'ai ajouté le conflit ne rien faire

La raison pour laquelle cela vous semble bizarre est que vous pensez à l'incrément sur le compteur dans le cadre de l'opération d'insertion, et donc le "NE RIEN FAIRE" devrait signifier "ne rien incrémenter". Vous imaginez ceci :

  1. Cochez les valeurs à insérer par rapport à la contrainte
  2. Si un doublon est détecté, abandonnez
  3. Séquence d'incrémentation
  4. Insérer des données

Mais en fait, l'incrément doit avoir lieu avant que l'insertion ne soit tentée . Un SERIAL la colonne dans Postgres est implémentée en tant que DEFAULT qui exécute le nextval() fonction sur une SEQUENCE liée . Avant que le SGBD puisse faire quoi que ce soit avec les données, il doit avoir un ensemble complet de colonnes, donc l'ordre des opérations est le suivant :

  1. Résoudre les valeurs par défaut, y compris l'incrémentation de la séquence
  2. Cochez les valeurs à insérer par rapport à la contrainte
  3. Si un doublon est détecté, abandonnez
  4. Insérer des données

Cela peut être vu intuitivement si la clé en double se trouve dans le champ d'auto-incrémentation lui-même :

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;

De toute évidence, cela ne peut pas savoir s'il y a un conflit sans incrémenter la séquence, donc le "ne rien faire" doit venir après cet incrément.