MySQL错误1062本质是违反唯一约束,报错含“Duplicate entry 'xxx' for key 'yyy'”;避免方式:INSERT IGNORE(静默跳过)、ON DUPLICATE KEY UPDATE(冲突更新)、INSERT...WHERE NOT EXISTS(前置校验);加唯一索引前须查删重复数据;建议显式命名唯一索引以利排查。

看到 Duplicate entry 报错就停,别急着删数据
MySQL 错误 1062 的本质是违反了唯一约束(UNIQUE 或 PRIMARY KEY),不是语法错误,也不是连接问题。报错信息里一定包含 Duplicate entry 'xxx' for key 'yyy',其中 'xxx' 是冲突的值,'yyy' 是触发约束的索引名(可能是列名、联合索引名或自动生成的名字如 uk_email)。直接忽略这个提示去重试 INSERT,只会再次失败。
INSERT 时避免 1062 的三种实用写法
根据业务意图选择合适方式,而不是统一用 IGNORE 或 REPLACE:
-
想跳过重复:用
INSERT IGNORE—— 遇到冲突静默丢弃整行,不报错也不插入;但注意它会吞掉其他类型的错误(比如字段长度超限),且不返回受影响行数为 0 的明确信号 -
想更新已有记录:用
INSERT ... ON DUPLICATE KEY UPDATE—— 最常用也最可控,例如INSERT INTO users (id, name) VALUES (1, 'Alice') ON DUPLICATE KEY UPDATE name = VALUES(name);注意VALUES(col)引用的是本次 INSERT 的值,不是当前行旧值 -
想严格确保只新增:用
INSERT SELECT ... WHERE NOT EXISTS—— 适合需要前置校验逻辑的场景,比如插入前比对多个条件;缺点是语句稍长,且在高并发下仍可能因间隙锁不足引发冲突
ALTER TABLE 加唯一索引时卡住或报 1062 怎么办
这是典型的数据预检查失败。MySQL 在添加 UNIQUE 约束前会扫描全表,只要发现任意两行在目标列上值相同,就立刻报 1062 并中止操作。
- 先查出重复项:
SELECT col, COUNT(*) FROM table_name GROUP BY col HAVING COUNT(*) > 1 - 确认是否真要保留这些重复——有时是脏数据,有时是业务允许的(比如状态字段未清理)
- 若需清理,优先用
DELETE+ 子查询或ROW_NUMBER()(MySQL 8.0+)去重,不要依赖ALTER IGNORE TABLE(5.7 已废弃,8.0 移除) - 加索引建议在低峰期执行,避免长事务阻塞 DML
唯一索引名没起好,查起来特别费劲
MySQL 自动生成的约束名(如 users_ibfk_1 或 uk_email_2)无法反映业务含义,排查 1062 时得反复查 SHOW CREATE TABLE 才能定位哪一列被限制。下次建表或加索引时,显式命名:
ALTER TABLE users ADD UNIQUE KEY uk_user_email (email);
这样报错里的 for key 'uk_user_email' 一眼就知道是邮箱重复。联合索引同理:UNIQUE KEY uk_order_user_status (user_id, status)。名字不用太长,但必须能和业务实体对应。










