UPSERT betekent "invoegen, of bijwerken als het al bestaat." PostgreSQL implementeert dit met INSERT ... ON CONFLICT — voeg een rij in, maar als dit een unique constraint zou schenden, werk dan in plaats daarvan de bestaande rij bij (of doe niets). Het handelt de veelvoorkomende "insert-or-update"-behoefte atomisch af.
Het probleem dat UPSERT oplost
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)
