UPSERT signifie « insérer, ou mettre à jour si cela existe déjà ». PostgreSQL implémente ceci avec INSERT ... ON CONFLICT — insérer une ligne, mais si elle viole une contrainte d'unicité, mettre à jour la ligne existante à la place (ou ne rien faire). Cela gère le besoin courant « insérer-ou-mettre-à-jour » de manière atomique.
Le problème qu'UPSERT résout
You want to insert a row, but it might already exist (by a unique key):
❌ a plain INSERT fails with a unique-violation error if it exists
❌ check-then-insert (SELECT, then INSERT or UPDATE) has a RACE CONDITION
(another transaction could insert between your check and insert)
→ ON CONFLICT does it atomically in ONE statement (no race condition)
