结构同步不会触发主键冲突,报duplicate entry错误说明实际执行了数据同步;需检查是否勾选synchronize data、preview中是否有insert语句、key mapping是否正确及目标表是否已有数据。
navicat 16 的「模型同步」(即结构同步)本身不会触发主键冲突——报 duplicate entry 错误,说明你实际执行的是数据同步,或误启了数据写入选项。
为什么结构同步会报 Duplicate entry 'X' for key 'PRIMARY'
结构同步只生成 ALTER TABLE、ADD INDEX 等 DDL 语句,不包含任何 INSERT。一旦看到这个错误,立刻检查:
- 同步向导 Step 1 的「Options」页是否勾选了
Synchronize data—— 勾了就不是纯结构同步 - 点击「Preview」后,SQL 预览里是否出现大量
INSERT INTO或REPLACE INTO—— 出现即证明走的是数据路径 - 目标库表是否已有数据,而你又在结构同步时勾选了
Truncate before insert或Delete before insert(这些属于数据操作行为,不在结构同步职责内)
如何确认并修正 Key Mapping 错误
即使你本意是做结构同步,但若后续立刻点「Synchronize」且源/目标表主键定义不一致(比如一边是 INT、一边是 BIGINT),Navicat 在比对阶段可能误判记录为「新增」,导致生成的 SQL 含 INSERT 并最终冲突。关键检查点:
- 进入 Step 2 「Key Mapping」:必须手动确认用于匹配的字段确实是目标表的主键(如
id),不能依赖自动映射 - 若表有复合主键,所有组成字段都必须勾选为 Key;缺一个,Navicat 就退化为全量插入逻辑
- 预览时点击某张表 → 底部切换到「Difference」标签页 → 查看被标为
Insert的行是否本应是Update;如果是,说明 Key Mapping 错了,或主键值类型/长度不兼容(例如源是INT UNSIGNED,目标是INT SIGNED)
导出 SQL 后安全替换 INSERT 的实操要点
当确认需要保留数据写入逻辑(比如你确实在做结构+数据联合同步),又想绕过主键冲突,导出 SQL 手动修改是最可控方式:
- 同步向导最后一步,务必勾选
Generate synchronization SQL script并指定保存路径 - 用编辑器打开 .sql 文件,全局搜索
INSERT INTO `table_name`(注意反引号),替换成INSERT IGNORE INTO `table_name` - 若需覆盖旧值(比如以新时间戳为准),可替换为
REPLACE INTO `table_name`,但注意:REPLACE INTO会重置自增 ID、触发ON DELETE行为、清空ON UPDATE CURRENT_TIMESTAMP字段 - 执行前先在目标库运行
SET FOREIGN_KEY_CHECKS = 0;,避免外键中断批量执行;执行完再补SET FOREIGN_KEY_CHECKS = 1;
真正容易被忽略的点是:Navicat 16 的「Skip duplicate key errors」选项只在纯数据同步的「错误处理」页生效,结构同步界面里压根不出现这个开关;而且它仅对 INSERT 生效,对 UPDATE 和外键约束无影响。别指望勾一下就万事大吉——先分清你在同步结构还是数据,再决定从哪一层下手。











