UPSERT = "insert nếu chưa có, update nếu đã có" trong một câu lệnh nguyên tử. Tránh mẫu sai kinh điển "kiểm tra trước rồi ghi" (SELECT → nếu không có thì INSERT), vốn dính race condition: hai request cùng thấy "chưa có" rồi cùng INSERT → lỗi trùng khóa hoặc dữ liệu nhân đôi.
PostgreSQL dùng INSERT ... ON CONFLICT:
sql
INSERT INTO counters (key, count)
VALUES ('page_view', 1)
ON CONFLICT (key)
DO UPDATE SET count = counters.count + 1;ON CONFLICT (cột)— chỉ ra ràng buộc unique/PK để phát hiện trùng.DO UPDATE SET ...— hành động khi trùng (truy cập giá trị mới quaEXCLUDED).DO NOTHING— bỏ qua nếu trùng, không lỗi.
Lợi ích:
- Nguyên tử, tránh race condition mà không cần khóa/transaction thủ công.
- Làm thao tác idempotent: chạy lại cùng dữ liệu không gây trùng — quan trọng cho retry, đồng bộ, webhook.
Chuẩn SQL và các hệ khác dùng MERGE; MySQL có INSERT ... ON DUPLICATE KEY UPDATE. Cần có ràng buộc unique/PK thì UPSERT mới biết thế nào là "trùng".