INSERT IGNORE仅在PRIMARY KEY或UNIQUE约束冲突时静默忽略,无唯一索引则报错;ON DUPLICATE KEY UPDATE则在冲突时执行更新逻辑,并影响LAST_INSERT_ID()返回值。
INSERT IGNORE 为什么没跳过重复数据
常见现象是执行 insert ignore 后,依然报错 duplicate entry 'xxx' for key 'primary' 或直接插入失败。根本原因不是语法写错了,而是表里缺唯一约束——insert ignore 只在遇到 primary key 或 unique 约束冲突时才静默忽略,普通索引或没建索引的字段完全不起作用。
实操建议:
- 先查表结构:
SHOW CREATE TABLE `your_table`;,确认目标字段(比如email)是否带UNIQUE或是主键 - 如果只是想按业务逻辑去重(如“邮箱已存在就不插”),但当前字段没唯一索引,得先加:
ALTER TABLE `users` ADD UNIQUE (`email`); - 注意:加唯一索引会失败如果表里已有重复值,得先清理:
DELETE t1 FROM users t1 INNER JOIN users t2 WHERE t1.id > t2.id AND t1.email = t2.email;
ON DUPLICATE KEY UPDATE 执行后没更新,字段还是 NULL
典型场景是用 INSERT ... ON DUPLICATE KEY UPDATE 想实现“存在就更新时间戳”,结果发现 updated_at 没变,甚至整行被设成 NULL。问题往往出在 UPDATE 子句里用了未定义变量或写了错误字段名。
实操建议:
-
ON DUPLICATE KEY UPDATE后面只能跟字段赋值,不能调函数或子查询(除非 MySQL 8.0+ 且上下文支持),例如updated_at = NOW()是合法的,但updated_at = (SELECT NOW())在老版本会报错 - 别漏掉
VALUES()函数:想把插入值原样更新回去,得写name = VALUES(name),而不是name = name(后者是当前行旧值) - 如果主键是自增
id,但你靠email唯一冲突,那ON DUPLICATE KEY只响应email冲突,不会管id是否重复
phpMyAdmin 里粘贴多条 INSERT 语句失败
很多人在 phpMyAdmin 的 SQL 标签页里一次性粘贴十几条带 INSERT IGNORE 或 ON DUPLICATE KEY 的语句,点执行后只成功第一条,后面全报错 You have an error in your SQL syntax。这不是语法问题,是 phpMyAdmin 默认关闭了多语句执行(mysqli.multi_query),而且分号会被当语句结束符截断。
实操建议:
- 单条执行最稳:每次只粘贴一条完整
INSERT语句,尤其上线前别图快批量跑 - 真要批量,改用
INSERT ... VALUES (...), (...), (...)合并成一条(注意总长度别超max_allowed_packet) - phpMyAdmin 设置里没有开关能一键打开多语句,强行开启有安全风险,不建议折腾
INSERT IGNORE 和 ON DUPLICATE KEY 的行为差异到底在哪
不是“哪个更好”,而是“触发条件和副作用完全不同”。比如你有一张用户表,email 是唯一键,status 默认 'pending'。用 INSERT IGNORE 插入已存在的 email,整条语句被丢弃,status 不变;而 ON DUPLICATE KEY UPDATE status = 'active' 会真的执行更新。
关键区别:
-
INSERT IGNORE是“要么全插,要么全丢”,不修改已有行,也不触发AUTO_INCREMENT值递增(但有些 MySQL 版本在事务中会预占 ID) -
ON DUPLICATE KEY UPDATE是“插失败就转成 UPDATE”,会真正执行 SET 后的逻辑,也会触发对应字段的更新时间戳、触发器等 - 性能上,两者底层都走唯一索引查找,差别不大;但如果 UPDATE 子句里有函数(如
NOW()),ON DUPLICATE KEY会每次执行,IGNORE则完全不碰
最容易被忽略的是:这两者对 LAST_INSERT_ID() 的影响不同。INSERT IGNORE 重复时返回 0,ON DUPLICATE KEY UPDATE 重复时返回原记录的 ID——如果代码里依赖这个值做后续操作,不测清楚会出隐蔽 bug。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











