insert ignore仅在表存在primary key或unique约束时生效,否则行为等同普通insert;它不比对字段值,只依赖索引触发冲突检测,无对应索引则完全无效,且复合索引需整组值重复才触发忽略。

必须确保表有 PRIMARY KEY 或 UNIQUE 约束,否则 INSERT IGNORE 完全不生效,行为和普通 INSERT 一模一样。
为什么 INSERT IGNORE 没跳过重复数据?
最常见原因是表上根本没建对应字段的唯一约束。MySQL 不会比对字段值是否重复,它只靠索引触发冲突检测。
- 执行
SHOW CREATE TABLE your_table;,确认输出里真有类似PRIMARY KEY (`id`)或UNIQUE KEY `uk_email` (`email`)的定义 - 如果只有
KEY `idx_user` (`user_id`)这种普通索引,INSERT IGNORE对它完全无效 - 已有重复数据时,
ALTER TABLE ... ADD UNIQUE会失败,得先清理(如用GROUP BY+MIN(id)保留一条)
复合唯一索引下怎么让 INSERT IGNORE 生效?
必须整组字段值完全重复才触发忽略,单字段匹配不够。
- 例如建了
UNIQUE (user_id, category),但插入只提供user_id = 1,不会触发跳过 - 插入语句中字段顺序无关,只要
(user_id, category)的值组合与某行完全一致,就会被忽略 - 注意:多个
NULL值在唯一索引中不视为重复,INSERT IGNORE会照常插入
批量插入时怎么判断哪几行被跳过了?
INSERT IGNORE 是逐行判断的,返回的受影响行数只反映新增数量,不能直接定位被跳过的行。
-
mysql_affected_rows()返回 0 表示“全被跳过”或“全失败”,需结合SHOW WARNINGS;查看具体警告(如Duplicate entry 'xxx' for key 'PRIMARY') - 返回值为 2,VALUES 有 5 行 → 至少 3 行被跳过(但无法知道是哪几行)
- 事务中前面成功的行不会因后面某行被跳过而回滚,
INSERT IGNORE本身不提供原子性保障
真正容易被忽略的是:唯一索引必须覆盖你业务上定义的“重复维度”。比如认为 (user_id, event_type) 组合不能重复,那就得建复合唯一索引,而不是只给 user_id 加唯一。少一个字段,IGNORE 就彻底失效。











