Navicat结构比对存在四大陷阱:一是TEXT字段未显式声明字符集导致比对失效;二是注释空格或标点差异触发误报;三是TINYINT(1)与BOOLEAN在DDL层被视为不同;四是字符集与排序规则差异被笼统归为“结构不一致”,需手动开启对应比对选项。
字段字符集未显式声明导致 TEXT 类型比对失效
navicat 16 默认跳过 text/blob 字段的字符集比对,除非你手动关闭 ignore text/blob column attributes。但即使关了,它仍只识别显式写在 create table 里的 character set 子句——如果表级默认是 utf8mb4,而 content text 字段没写 character set utf8mb4,navicat 就认为它“无字符集”,和另一端显式声明了 character set latin1 的同名字段比对时,就会标为差异。
验证方法很简单:SHOW CREATE TABLE table_name,看 TEXT 字段是否带 CHARACTER SET;修复方式也直接:要么在目标库补全声明,要么导出 DDL 时强制生成显式字符集。
表/字段注释里一个空格都会触发“结构不同”
Navicat 默认比对注释(包括表注释和字段注释),且是精确字符串匹配。源库注释是 '用户表',目标库是 '用户表 '(末尾多一个空格),或用了中文顿号 vs 英文逗号,都会被标红。
解决办法是在比对前打开 Compare Options → 勾选 Ignore comments(注意:这个选项名字叫 “Ignore”,勾选才表示“忽略”);但必须在点击 Compare 按钮之前设置,之后改无效。
- 如果只希望忽略字段注释,不忽略表注释,要单独勾选
Ignore column comments - PostgreSQL 或 SQL Server 用户注意:
Ignore comments对 MySQL 表注释有效,但对 SQL Server 的扩展属性可能不生效
tinyint(1) 和 boolean 在 DDL 层根本不等价
MySQL 底层把 BOOLEAN 当作 TINYINT(1) 别名,但 Navicat 比对的是原始 DDL 输出。开发库建表用的是 is_active BOOLEAN,生产库是 is_active TINYINT(1),两者 DDL 字符串不同,Navicat 就会标为“类型变更”。
新版 Navicat 16+ 提供了 Ignore tinyint(1) vs boolean 选项(在 Compare settings 里),勾选即可过滤这类语义等价但语法不同的干扰项。如果没有该选项,建议导出 HTML 报告后手动跳过,重点关注 VARCHAR → TEXT、NOT NULL ↔ NULL 等真实风险变更。
字符集与排序规则差异被归入“整体结构不一致”而非单独提示
Navicat 不会单独标出“collation 不同”,而是把 utf8mb4_0900_ai_ci 和 utf8mb4_unicode_ci 的差异笼统显示为字段“结构不一致”。想让它真正识别并分类显示,必须在 对象比较设置 中主动勾选 Compare collations 和 Compare column character sets。
否则你手动改了目标库的 collation,比对结果可能还是“无差异”,但同步脚本执行时却失败——因为 Navicat 生成的 ALTER 语句试图写入不支持的 collation,或权限不足。
最容易被忽略的一点:这些选项开关只影响本次比对,每次新开结构同步窗口都得重新确认,没有全局默认设置。











