首页/数据/SQL 速查/Upsert:ON DUPLICATE KEY UPDATE 与 ON CONFLICT
本包目录(311 条)
查询基础33 条连接与子查询40 条聚合与窗口函数54 条函数速查60 条
变更与事务52 条
性能与执行计划72 条

Upsert:ON DUPLICATE KEY UPDATE 与 ON CONFLICT

“存在则更新、不存在则插入”:MySQL 用 ON DUPLICATE KEY UPDATE,PostgreSQL 用 ON CONFLICT,是幂等写入的基础写法。

SQL 速查数据更新于 2026-10-12

MySQL

MySQL
INSERT INTO counters (name, cnt)
VALUES ('pv', 1) AS new
ON DUPLICATE KEY UPDATE cnt = cnt + new.cnt;

-- 8.0.20 起推荐行别名;旧的 VALUES(col) 写法已废弃

PostgreSQL

PostgreSQL
INSERT INTO counters (name, cnt)
VALUES ('pv', 1)
ON CONFLICT (name)
DO UPDATE SET cnt = counters.cnt + EXCLUDED.cnt;

-- 只跳过冲突
INSERT INTO counters (name, cnt) VALUES ('pv', 1)
ON CONFLICT (name) DO NOTHING;
冲突依据MySQL:任意 UNIQUE/主键冲突都触发;PG:只认冲突目标列(列上需有唯一约束)
原子性两库都是单语句原子操作,比“先查再插”并发安全
自增MySQL 冲突走 UPDATE 时 AUTO_INCREMENT 仍可能前进,留下空洞

易错点

  • MySQL 的 upsert 不指定冲突列:任何唯一键冲突都会命中,表上有多个唯一索引时结果可能不符合预期
  • PostgreSQL 的 ON CONFLICT (col) 要求 col 上有唯一索引或约束,否则报 there is no unique or exclusion constraint

数据来源与参考

  • MySQL 8.0 Reference Manual · INSERT ... ON DUPLICATE KEY UPDATE
  • PostgreSQL Documentation · INSERT
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌