navicat模型对比基于缓存快照而非实时元数据,需手动刷新连接和模型文件;命名不一致会导致表被静默忽略;enum顺序、comment等变更默认不提示;ddl标准化引发假阳性差异;跨库依赖、权限、引擎兼容性等问题无法检测。
navicat模型对比不是实时元数据比对,它比的是缓存快照
navicat的「模型对比」(model comparison)功能不直接查询数据库的information_schema或show create table,而是基于你上次打开模型文件或连接时加载的结构快照做差异计算。这意味着如果生产库刚执行过alter table ... add column但没刷新连接,对比结果会漏掉这个字段。
常见错误现象:明明生产库已加了status字段,模型对比却显示“无差异”;或者模型里删了deleted_at,但对比结果没提示要DROP——大概率是模型或连接缓存未更新。
- 对比前必须在生产库连接上右键 → 刷新,或执行
FLUSH TABLES清空服务端缓存 - 模型文件(.nmf)需用最新版Navicat打开并保存一次,否则旧版本可能忽略MySQL 8.0+的invisible index、generated column等新特性
-
ENUM值顺序变化、COMMENT文字微调、COLUMN_FORMAT变更,默认不触发差异提示,需手动勾选“Compare column comments”和“Compare column format”
模型名与表名不一致时,Navicat不会自动映射
如果你的模型里表叫user_profile,而生产库实际是t_user_profile,Navicat不会尝试匹配,直接跳过该表对比,也不会报错——结果里就“消失”了。
使用场景:团队用ER图建模时习惯加前缀/后缀,上线后DBA按规范统一命名,这种命名偏差会导致关键表被静默忽略。
- 确保模型中每个表的
Physical Name(右键表→编辑属性→常规页签)与生产库SHOW TABLES输出的名称完全一致 - 跨环境部署时,别依赖“模型导出为SQL再执行”,因为Navicat生成的DDL默认不含
IF NOT EXISTS,也不处理ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs这类显式声明,容易因目标库默认配置不同而失败 - 若模型含视图/存储过程,需确认生产库连接权限包含
SELECTonmysql.proc(MySQL)或pg_proc(PostgreSQL),否则这些对象不参与对比
对比结果里的“修改”可能只是语法格式差异,不是真实变更
Navicat解析DDL后会标准化输出,比如把INT(11) UNSIGNED转成INTEGER UNSIGNED,把datetime NOT NULL DEFAULT '1970-01-01'简化为DATETIME NOT NULL。这会导致模型和生产库明明结构一致,却被标为“字段定义不同”。
性能影响:这类假阳性差异越多,生成的同步脚本越冗长,人工审查成本越高;更危险的是,误删重建索引可能引发锁表。
- 点开差异项右侧的
View DDL Comparison按钮,逐行比对原始DDL字符串,而非只看左侧操作类型(ADD/MODIFY/DROP) - 注意
COLLATE是否被省略:模型里写VARCHAR(50) COLLATE utf8mb4_unicode_ci,生产库是VARCHAR(50)(依赖表级默认),Navicat会标为差异,但实际行为可能一致 - 函数索引(如
KEY ((JSON_EXTRACT(data, '$.name'))))必须两边写法完全相同,大小写、空格、括号位置差一点就判定为不一致
模型对比无法发现跨库依赖和权限问题
模型文件里画了个视图v_user_summary,定义是SELECT * FROM prod_db.users,但生产库中prod_db不存在,或当前用户没有SELECT权限——Navicat模型对比完全不检查这些,只会告诉你“视图结构一致”。
容易踩的坑:直接按对比结果运行同步脚本,结果CREATE VIEW报错ERROR 1146 (42S02): Table 'prod_db.users' doesn't exist,而日志里没有任何前置预警。
- 模型中所有跨库引用(
db_name.table_name)、存储过程调用的外部函数、触发器涉及的权限,都得人工核对生产库实际状态 - 涉及
FEDERATED、CONNECT引擎的表,Navicat不校验远程库连通性,对比通过≠能创建成功 - 模型里设了
DEFINER='admin'@'%',但生产库没这个用户,同步时会静默降级为DEFINER=CURRENT_USER,导致后续调用权限异常
模型对比真正可靠的边界,是同一套设计文档落地到单个数据库实例的过程验证。一旦涉及跨库引用、权限链、运行时依赖或缓存未刷新,就必须跳出界面,用SHOW CREATE TABLE、SELECT COUNT(*) FROM information_schema.columns这些底层命令交叉验证。











