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();Связанные термины
Анекдоты по теме
— Как изменить тип колонки в PostgreSQL? — ALTER TABLE orders ALTER COLUMN amount TYPE NUMERIC(15,2); — А если таблица большая? — PostgreSQL перепишет всю таблицу. На время — ACCESS EXCLUSIVE LOCK. — Как сделать без простоя? — Добавить новую колонку, мигрировать данные батчами, переключить приложение, удалить старую.
Начинающий: — Я выучил SQL за неделю! Опытный: — Поздравляю. Ты выучил SELECT, INSERT, UPDATE, DELETE. Осталось лет 5 на JOIN, индексы, транзакции и почему NULL — это зло. Удачи.
DBA объясняет жене: — Дорогая, я как FOREIGN KEY. Я всегда ссылаюсь на тебя — мою PRIMARY KEY. Жена: — А если я удалюсь? DBA: — Тогда я не смогу существовать. Будет ошибка.