Navicat结构同步本身不触发主键冲突,报“Duplicate entry”错误说明实际执行的是数据同步或误启了Synchronize data选项;应检查Options页是否勾选该选项、预览SQL是否含INSERT语句,并确认Key Mapping准确匹配主键。
navicat 同步模型(即结构同步)本身不触发主键冲突——主键冲突只发生在数据写入阶段。你遇到的“同步模型时主键冲突”,实际是误用了「结构同步」功能去干「数据同步」的活,或者在结构同步后立刻执行了隐含的数据操作(比如勾选了 synchronize data)。真正要解决的,是结构已一致前提下、后续数据同步环节的主键重复问题。
为什么结构同步会报 Duplicate entry 错误
结构同步(Structure Synchronization)只生成 ALTER TABLE、CREATE INDEX 等 DDL 语句,不产生 INSERT。如果你看到 Duplicate entry '1' for key 'PRIMARY' 这类错误,说明 Navicat 实际执行的是数据同步任务,或你在结构同步设置里误启了 Synchronize data 选项。
- 检查同步向导 Step 1 的「Options」页:确认未勾选
Synchronize data - 查看生成的 SQL 预览:如果出现大量
INSERT INTO,那就不是纯结构同步 - 结构同步失败报错通常是
ERROR 1060 (42S21)(重复列)、ERROR 1091 (42000)(无法删除不存在的列),而非 1062
对比结果里手动筛选更新项的实操要点
Navicat 的「Compare & Preview」界面显示的 Insert/Update/Delete 行数,本质是基于主键或唯一键匹配后的差异计算。但默认只用主键比对,若表无主键或你改过 Key Mapping,就会把本该 Update 的行判成 Insert,导致主键冲突。
- 进入 Step 2「Key Mapping」:必须手动确认用于比对的字段确实是目标表的主键(如
id),不能依赖自动映射 - 若表有复合主键,需全部字段勾选为 Key,缺一个就退化为全量插入
- 预览时点击某张表 → 底部切换到「Difference」标签页 → 查看具体哪些行被标为
Insert;如果是已有主键的记录,说明 Key Mapping 错了或源/目标主键值类型不一致(比如一边是INT、一边是BIGINT) - 右键单条记录 → 取消勾选,可临时跳过该行;但批量操作只能靠导出 SQL 后手动删减
导出 SQL 后如何安全修改插入逻辑
直接勾选「Skip duplicate key errors」看似省事,但会静默跳过所有冲突行,无法审计丢了多少数据。更可控的做法是导出 SQL,把 INSERT INTO 改成 INSERT IGNORE INTO 或 REPLACE INTO,再人工校验。
- 同步向导最后一步 → 勾选
Generate synchronization SQL script并指定路径 - 打开生成的 .sql 文件,查找所有
INSERT INTO `table_name`,替换为INSERT IGNORE INTO `table_name` - 注意:若表有自增主键 + 外键引用,
REPLACE INTO会先 DELETE 再 INSERT,可能触发级联删除,慎用 - 执行前先在测试库运行:
mysql -u user -p database ,观察 warning 数量(<code>Warning: 1062即跳过的主键冲突行)
容易被忽略的底层陷阱
很多主键冲突根本不在 Navicat 界面里显形,而是藏在字段定义细节里:
-
INT和INT UNSIGNED被 Navicat 当作不同类型,即使值相同也会判为不匹配,导致重复插入 - MySQL 8.0+ 的
utf8mb4_0900_as_cs排序规则与旧版utf8mb4_general_ci不兼容,字符串主键(如 UUID)比对失败,转而走全表扫描式插入 - 目标表若定义了
ON DUPLICATE KEY UPDATE,但 Navicat 导出的 SQL 没包含该子句,照样报 1062
真正的关键不在“怎么跳过”,而在“为什么会被当成新记录”——得回到 Key Mapping 和字段类型一致性上抠细节。


















