PostgreSQLСредний
UPSERT (ON CONFLICT)
Вставляет строку или обновляет её при конфликте уникального ключа. Атомарная операция.
Синтаксис
INSERT INTO table (cols) VALUES (...) ON CONFLICT (unique_col) DO UPDATE SET col = EXCLUDED.col;
Объяснение
UPSERT = INSERT + UPDATE при конфликте. В PostgreSQL: ON CONFLICT DO UPDATE или ON CONFLICT DO NOTHING.
Атомарен — нет race condition между проверкой и вставкой. Безопаснее, чем проверять через SELECT + INSERT/UPDATE в приложении.
Пример
-- Атомарный счётчик
INSERT INTO page_views (page, views) VALUES ('home', 1)
ON CONFLICT (page) DO UPDATE
SET views = page_views.views + 1;
-- Обновить профиль или создать
INSERT INTO profiles (user_id, bio) VALUES ($1, $2)
ON CONFLICT (user_id) DO UPDATE
SET bio = EXCLUDED.bio, updated_at = NOW();Связанные термины
Анекдоты по теме
— Какая оконная функция самая печальная? — LAG(). Потому что она всегда оглядывается на прошлое и никогда не смотрит вперёд.
DBA объясняет жене: — Дорогая, я как FOREIGN KEY. Я всегда ссылаюсь на тебя — мою PRIMARY KEY. Жена: — А если я удалюсь? DBA: — Тогда я не смогу существовать. Будет ошибка.
— Как хранить деньги в базе данных? — DECIMAL(19,4) или NUMERIC(19,4). — Почему не FLOAT? — Потому что FLOAT неточный. 0.1 + 0.2 = 0.30000000000000004. — В банке это было бы проблемой. — Именно.