
INSERT IGNORE 本质是跳过重复键错误
它不是“智能去重”,而是遇到 Duplicate entry 这类由唯一索引(PRIMARY KEY 或 UNIQUE)触发的错误时,直接忽略整条语句,不报错也不插入。没建对应索引?INSERT IGNORE 和普通 INSERT 行为完全一样,照样报错或成功。
- 必须已有
UNIQUE或PRIMARY KEY约束,否则无效 - 只对违反这些约束的错误静默处理,其他错误(如字段超长、类型不匹配)仍会报错
- 返回值中
affected rows为 0 表示被忽略,1 表示成功插入
INSERT IGNORE 和 REPLACE INTO 不是一回事
REPLACE INTO 看起来也“处理重复”,但逻辑完全不同:先删后插。如果表有自增主键,且你用的是非主键字段做唯一判断,REPLACE INTO 会删除旧行再插入新行,导致 id 变化、外键关联断裂、触发器重复执行——而 INSERT IGNORE 完全不动原有数据。
- 想保留原记录就用
INSERT IGNORE;想强制更新整行才考虑REPLACE INTO -
REPLACE INTO在有多个唯一索引时可能意外删除多条匹配行(按所有唯一索引匹配) -
INSERT IGNORE更安全,但无法更新已存在行的其他字段
真正要更新字段时,别硬套 INSERT IGNORE
如果目标是“有则更新、无则插入”,INSERT IGNORE 做不到。它只会跳过,不会改。这时候该用 INSERT ... ON DUPLICATE KEY UPDATE。
-
INSERT IGNORE后面不能跟UPDATE子句,语法直接报错 -
ON DUPLICATE KEY UPDATE能指定哪些字段更新,比如UPDATE status = VALUES(status), updated_at = NOW() - 注意
VALUES(col)是指本次INSERT中该列的值,不是当前行原值
INSERT INTO users (id, name, score) VALUES (1, 'Alice', 95) ON DUPLICATE KEY UPDATE score = VALUES(score), updated_at = NOW();
批量插入时 IGNORE 的行为容易误判
一条 INSERT IGNORE 语句含多行数据时,MySQL 是逐行判断:某行因唯一冲突被忽略,不影响后续行继续尝试插入。但很多人以为“整批失败”或“全部跳过”,其实不是。
- 即使第一行被忽略,第二、三行仍会检查并可能成功插入
- 返回的
affected rows是实际新增行数,不是总行数减去冲突数 - 若用
LOAD DATA INFILE ... IGNORE,行为类似,也是行级忽略










