UPSERT (ON CONFLICT)
Вставляет строку или обновляет её при конфликте уникального ключа. Атомарная операция.
INSERT INTO table (cols) VALUES (...)
ON CONFLICT (unique_col) DO UPDATE
SET col = EXCLUDED.col;Объяснение
Пример
-- Атомарный счётчик
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();Связанные термины
Анекдоты по теме
— Когда денормализация оправдана? — Когда JOIN слишком дорог для критичных запросов. — Примеры? — Материализованные агрегаты: сохранить total_orders в таблице users. — Дублирование для аналитики: OLAP схемы специально денормализованы. — Риски? — Несогласованность. Нужны триггеры или приложение для синхронизации.
— Зачем нужен NOT NULL DEFAULT вместо просто DEFAULT? — ALTER TABLE users ADD COLUMN score INT DEFAULT 0; — В PostgreSQL с 11 версии это мгновенно. — Раньше? — До PostgreSQL 11 добавление колонки с NOT NULL DEFAULT переписывало всю таблицу. — Хорошо что обновились. — Ещё как.
Преподаватель: — Что такое UNION? Студент: — Это когда ты берёшь два списка и склеиваешь их в один. Преподаватель: — А UNION ALL? Студент: — А это когда даже дубликаты не выкидываешь. Лень убирать повторы.