首页/数据/数据库速查/INSERT IGNORE / ON DUPLICATE KEY UPDATE / REPLACE
SQL 语法52 条

INSERT IGNORE / ON DUPLICATE KEY UPDATE / REPLACE

三种冲突处理:IGNORE 跳过(可能吞掉其他错误)、ON DUPLICATE KEY UPDATE 更新(推荐)、REPLACE 先删后插(会触发级联)。

数据库速查数据更新于 2026-10-13

三种冲突处理是什么

写入遇到主键或唯一索引冲突时有三种处理方式:INSERT IGNORE 跳过冲突行并降级为警告;ON DUPLICATE KEY UPDATE 在冲突时更新指定列,也就是常说的 UPSERT;REPLACE 先删除旧行再插入新行。选型的关键是先明确「冲突时应该保留什么」,REPLACE 因为附带删除语义,代价常常被低估。

基本信息

触发条件主键或唯一索引冲突
IGNORE 行为跳过并产生警告,可用 SHOW WARNINGS 查看
UPSERT 行为更新指定列,可写成 cnt = cnt + 1 形式
REPLACE 行为删除旧行再插入,触发 DELETE 与 INSERT 触发器
版本特性MySQL 8.0.19 起 UPSERT 支持行别名引用新值

典型使用场景

  • 幂等写入:任务重跑时不因唯一键冲突而报错中断
  • 计数器累加:UPSERT 写成 cnt 加 1,一条语句完成累加
  • 配置覆盖:以配置名为唯一键,写入即覆盖最新值
  • 标签去重:IGNORE 让重复标签静默跳过
  • 数据同步:批量写入前先确认是否允许覆盖,避免误用 REPLACE
  • 部分列更新:UPSERT 只更新变化的列,保留其他字段现状

UPsert、IGNORE 与 REPLACE

UPsert、IGNORE 与 REPLACE
INSERT INTO counters (id, cnt) VALUES (1, 1)
ON DUPLICATE KEY UPDATE cnt = cnt + 1;                 -- 累加

INSERT INTO counters (id, cnt) VALUES (1, 10) AS new
ON DUPLICATE KEY UPDATE cnt = new.cnt + 1;             -- 8.0.19+ 行别名

INSERT IGNORE INTO tags (name) VALUES ('sql');         -- 冲突静默跳过
SHOW WARNINGS;                                          -- 查看被跳过的原因

REPLACE INTO kv_setting (k, v) VALUES ('theme', 'dark');   -- 先删后插
SELECT id, k, v FROM kv_setting WHERE k = 'theme';      -- 核对自增 id 是否变化

三种策略对照

策略冲突行为副作用
INSERT IGNORE跳过冲突行,产生警告会把数据截断等错误一并降级,掩盖问题
ON DUPLICATE KEY UPDATE更新指定列更新行数统计与预期不同,需按实际情况理解
REPLACE删除旧行后插入新行自增主键变化、触发触发器与级联删除
先查后写应用层判断再决定并发下有竞态,除非加锁或依赖唯一索引
REPLACE 会删除旧行再插入新行:自增 id 变化、触发器与级联外键都会被触发,能用 UPSERT 就别用 REPLACE。
INSERT IGNORE 会把类型转换失败、字段截断这类错误也降级成警告,问题被静默掩盖;需要严格数据校验时不要使用它。

易错点

  • 用 REPLACE 做数据更新,旧行被删除导致自增 ID 变化、关联表外键级联被触发
  • INSERT IGNORE 吞掉字段截断错误,写入的数据与预期不一致却没有任何报错
  • UPSERT 未加锁也未依赖唯一索引,先查后写在并发下产生重复数据
  • 批量 UPSERT 忘记控制批次大小,单条语句过大造成锁等待与主从延迟
  • 把 REPLACE 用在有触发器的表上,业务审计记录出现额外的删除与插入日志

数据来源与参考

  • MySQL 8.0 Reference Manual: INSERT ... ON DUPLICATE KEY UPDATE Statement

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌