nsert ignore / replace into / on duplicate key update 给我讲解一下

32 阅读2分钟

下面我用 最清晰、最实战、最容易理解 的方式,彻底讲清:

✅ 1. INSERT IGNORE

忽略冲突,不会报错,也不会更新已有数据

📌 场景

当插入数据时,如果遇到 唯一索引 / 主键冲突 ,MySQL 会自动忽略该行,不报错,不更新。

📌 示例

insert ignore into user(id, username)
values (1, 'zhang');

📌 结果

  • 若 id=1 不存在 → 正常插入
  • 若 id=1 已存在 → 这条语句 什么都不做(不报错、不更新)

✔ 适用场景

  • 你只想插入不存在的记录
  • 不想更新旧数据
  • 不想让系统因为冲突而报错

✅ 2. REPLACE INTO

先删除旧数据,再插入新数据(会触发删除 + 插入)

📌 行为如下:

  1. 检查主键/唯一索引是否冲突
  2. 若冲突 → ❗先 DELETE 删除旧行
  3. 再 INSERT 新行

📌 示例

replace into user(id, username)
values (1, 'newName');

📌 结果

  • 若 id=1 不存在 → 直接插入

  • 若 id=1 已存在 →

    • 旧数据被删除
    • 插入新的数据

⚠ 必须注意

  • 会触发 删除触发器、插入触发器
  • 会导致自增 id 变化
  • 会导致其他外键可能出问题
  • 性能比 insert ignoreon duplicate key update

✔ 适用场景

你确定冲突时应该 整个覆盖 数据,而不是修改一部分字段。


✅ 3. ON DUPLICATE KEY UPDATE

主键/唯一索引冲突时执行 UPDATE,不冲突时执行 INSERT

📌 行为

  • 若没有冲突 → INSERT
  • 若有冲突 → 执行 UPDATE(不会删除旧数据)

📌 示例

insert into user(id, username, age)
values (1, 'zhang', 18)
on duplicate key update
  username = values(username),
  age = values(age);

📌 结果

  • 若 id=1 不存在 → 插入
  • 若 id=1 已存在 → 更新 username, age

✔ 适用场景

平时最常用:

  • 插入新数据
  • 若存在,则更新部分字段(例如更新时间、数量累加等)

🔥 三者对比总结(牢记)

语句无冲突有冲突(主键/唯一)是否删除旧数据是否更新旧数据
insert ignore插入忽略,不报错❌ 不删除❌ 不更新
replace into插入先删旧,再插入新✔ 删除✔ 覆盖(插入新行)
on duplicate key update插入更新已有数据❌ 不删除✔ 更新

🔥 哪个最好?

场景推荐语句
只想插不存在的insert ignore
若存在就更新部分字段on duplicate key update ⭐最常用
完全覆盖旧数据(适合整行替换)replace into

💡 实战示例(你会经常用到)

1️⃣ 插入没问题、冲突直接略过

insert ignore into user(id, name) values (1, 'a');

2️⃣ 插入或更新

insert into user(id, score)
values (1, 10)
on duplicate key update score = score + 10;

3️⃣ 完全替换一条记录

replace into user(id, name, age)
values (1, 'newName', 20);