Navicat同步向导未识别UNIQUE索引,因仅当INFORMATION_SCHEMA.STATISTICS中NON_UNIQUE=0、索引名/类型/顺序与源表完全一致且结构同步已正确生成约束时,才将其纳入Key Mapping;否则退化为仅依赖主键匹配。
Navicat 同步向导没识别到 UNIQUE 索引,Key Mapping 里看不到对应字段
navicat 的 key mapping 列表只显示主键(primary key)和显式标记为「唯一索引」的列,但它不会自动把 unique 约束当匹配依据——除非该约束在数据库元信息中被正确注册为「唯一索引」。常见原因包括:
- 你用
ALTER TABLE ADD UNIQUE (email)添加约束,但 MySQL 实际建的是普通索引(无Non_unique = 0标志),Navicat 就不认 - 表是从旧版本 MySQL 迁入,
INFORMATION_SCHEMA.STATISTICS中Non_unique字段值为1(误标为非唯一) - 字段上建了
UNIQUE,但同时又设了NULL允许(MySQL 允许多行NULL,所以元数据可能降级为普通索引) - 使用了函数索引(如
UNIQUE (LOWER(email))),Navicat 15/16 不解析函数表达式,直接忽略整条索引
验证方法:在目标库执行 SELECT INDEX_NAME, NON_UNIQUE FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'users' AND SEQ_IN_INDEX = 1;,确认你要映射的索引行 NON_UNIQUE = 0。
手动添加唯一字段到 Key Mapping 后仍报 Duplicate entry
即使你强行把 email 拖进 Key Mapping,同步时还是报 Duplicate entry 'a@b.com' for key 'uk_email',说明 Navicat 并没真正按它走匹配逻辑。根本原因是:
- Navicat 只在「源表」和「目标表」都存在同名、同类型、同顺序的唯一索引时,才启用该字段做行比对;如果目标表索引名是
idx_email而不是uk_email,它就放弃使用 - 字段类型不一致:源是
VARCHAR(100) CHARACTER SET utf8mb4,目标是VARCHAR(100) CHARACTER SET utf8,Navicat 认为不可比,退回到主键匹配(若无主键则全量 INSERT) - 你勾选了
Insert records却没勾Update records,而目标库已有该email行 —— Navicat 发现“键存在”,但策略不允许更新,只能硬插,触发冲突
实操建议:先在目标库运行 SHOW CREATE TABLE users;,逐字比对索引定义是否与源库完全一致(包括名称、字段顺序、字符集、是否为前缀索引等)。
为什么勾了 Skip duplicate key errors 还是中断?
这个选项只对 MySQL 的 INSERT 语句生效,且仅跳过 ERROR 1062。但它不处理以下情况:
- 你同步的是 PostgreSQL,报错是
duplicate key violates unique constraint—— Navicat 15 不支持跳过,必须升级到 16+ 并开启Use upsert syntax - 冲突发生在
UPDATE阶段(比如你只勾了Update records,但源值触发了目标表另一个唯一约束),Skip duplicate key errors完全不生效 - 目标表有多个唯一键(
uk_email,uk_phone),而你只把email设为 Key Mapping,Navicat 匹配时发现 email 已存在就去 UPDATE,结果新 phone 值撞上uk_phone,报错类型仍是 1062,但已不在「INSERT 阶段」
此时日志里会看到类似 [Warning] Skipped 1 record due to duplicate key,但后续语句仍失败 —— 因为 warning 只针对 INSERT,error 是 UPDATE 引发的,无法跳过。
结构同步后 UNIQUE 约束消失,导致后续数据同步彻底失效
如果你刚做完「结构同步」,再立刻跑数据同步,却发现在 Key Mapping 里找不到任何唯一字段,大概率是结构同步本身没把 UNIQUE 约束写进去。常见原因:
- Navicat 默认关闭
Generate UNIQUE constraints(路径:Tools → Options → Data Synchronization → Advanced),尤其在旧版或跨版本同步时 - 源库是 MySQL 5.7,目标库是 8.0,Navicat 解析
SHOW CREATE TABLE时漏掉了UNIQUE KEY行(因 8.0 输出格式变更) - 你用了
mysqldump --skip-opt导出源结构,dump 文件里没包含UNIQUE定义,Navicat 从 dump 解析自然读不到
补救办法:不要依赖结构同步自动建约束。在目标库手动执行 ALTER TABLE users ADD UNIQUE KEY uk_email (email);,再刷新 Navicat 连接(右键连接 → Refresh),Key Mapping 才会重新加载该字段。


















