必须取消勾选“仅比较主键”,改选“比较所有记录”,否则Navicat只校验主键存在性而忽略字段值差异,导致status等关键字段不同却被判为一致,无法定位真实不一致行。
直接用「数据对比」功能,但必须关掉默认的“仅比较主键”模式,否则 navicat 只告诉你“某行存在/不存在”,根本不会比字段值——你看到的“数据量不一致”实际可能是字段内容不同被误判为多删少插。
为什么「数据对比」默认不显示具体差异行
Navicat 16 的「工具 → 数据对比」第二步配置里,默认勾选的是 仅比较主键(或类似表述,如“Compare primary key only”),它只校验源库有、目标库没有的主键值,完全忽略字段内容。结果就是:哪怕两行主键相同、但 status 字段一个为 'pending'、一个为 'done',它也标为“一致”。
你要找的是“数据量不一致的具体条目”,说明你已经发现行数对不上,那大概率是字段值差异导致 Navicat 在内部按全字段比对时触发了 INSERT/UPDATE/DELETE 决策,但预览页没展开看——这恰恰是因为你没强制它比所有字段。
- 必须手动取消勾选
仅比较主键,改选比较所有记录(Navicat 15/16 界面文字略有差异,但逻辑一致) - 若表无主键或唯一索引,Navicat 会退化为全字段比对,速度慢且结果列满屏;提前加
PRIMARY KEY或UNIQUE索引能大幅提速并让差异定位到行级 - 字符集不一致(如
utf8mb4vslatin1)会导致相同字符串被判定为不同,但界面不报错也不提示;执行SHOW CREATE TABLE table_name对比两边字符集和排序规则
预览页里怎么快速识别哪几行真不一致
进入「数据同步」向导后,在「高级」页之前,先点「下一步」跳到预览页——这里才是你真正该盯住的地方。它不是模拟,而是基于上一步比对结果实时算出的操作清单。
- 左侧列表显示各表的待执行动作,例如
orders 表:插入 0 行,更新 2 行,删除 1 行;如果只看到“删除 N 行”,说明目标库有多余数据,得确认是不是测试残留 - 点击任意表名,底部窗格立刻列出源 vs 目标对应行;不同字段值会用黄色背景高亮——注意看是不是只有
updated_at、modified_time这类自动更新字段不同,这种通常不用同步 - 右键某行 →
排除此项,可临时跳过单行;但别批量勾选“跳过所有更新”,否则可能漏掉业务关键字段变更 - 预览页不显示 WHERE 条件细节,所以无法区分“因主键冲突跳过”和“字段值相同忽略”;要看真实跳过情况,得等同步完成,翻「信息日志」页找
Duplicate entry '105' for key 'PRIMARY'这类警告
跨库比对时字段名/类型不一致怎么办
比如源库用 user_id 当主键,目标库叫 id;或者源是 DATETIME,目标是 TIMESTAMP WITH TIME ZONE——Navicat 不会自动映射,必须人工绑定。
- 在「数据对比」向导中,找到对应表右侧的齿轮图标 → 点击 → 在弹窗里手动把源库的
user_id和目标库的id拖拽绑定为匹配字段 - 时间字段若含时区偏移,务必在「高级选项」里取消勾选
Compare timestamp with timezone,否则同一时刻因存储格式不同被标红 - JSON 字段默认按字符串比对,
{"a":1,"b":2}和{"b":2,"a":1}会被判为不同;两边需提前用JSON_NORMALIZE()(MySQL 8.0+)或jsonb_strip_nulls()(PostgreSQL)处理再比 - SQL Server 的
uniqueidentifier和 MySQL 的CHAR(36)默认不兼容;比对前统一转成小写、去掉连字符,或在 Navicat 连接属性中启用Use Unicode
最容易被忽略的点是:Navicat 的「数据对比」结果依赖你当前连接的权限。如果你没有 SELECT 权限访问某张表,它不会报错,而是静默跳过——最终差异行数变少,你还以为数据真一致。动手前先确认账号对两个库的所有目标表都有完整读权限。


















