模型验证报“字段类型不匹配”但实际一致,本质是字符集或排序规则(collation)差异所致;Navicat模型验证会读取INFORMATION_SCHEMA.COLUMNS中的CHARACTER_SET_NAME和COLLATION_NAME,即使字段类型相同(如VARCHAR(100)),只要一边用utf8mb4_0900_as_cs、另一边用utf8mb4_general_ci,就会标红报错。
模型验证报“字段类型不匹配”但实际一致?检查字符集和排序规则
navicat 的模型验证(validate model)不是只比对 int 或 varchar(255) 这类表面定义,它会深入读取 information_schema.columns 中的 character_set_name 和 collation_name。哪怕两个字段都声明为 varchar(100),只要一边是 utf8mb4 + utf8mb4_0900_as_cs,另一边是 utf8mb4 + utf8mb4_general_ci,验证就会标红报错。
实操建议:
- 右键模型中对应表 → “对象信息” → 切到 “DDL” 标签页,复制建表语句,在目标库执行
SHOW CREATE TABLE对比真实字符集与排序规则 - 若用 Navicat 同步过模型,确认连接设置里勾选了 “Use real character set and collation”,否则它可能按默认值补全,掩盖差异
- MySQL 8.0+ 默认排序规则变更后,旧模型导出的 DDL 可能含已废弃的
COLLATE utf8mb4_unicode_ci,而新库实际用的是utf8mb4_0900_as_cs,验证时直接判定不一致
验证通过但同步失败?重点盯住外键约束名和引用动作
模型验证只检查语法合法性,不校验外键是否真能生效。常见陷阱是:模型里定义了 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,验证绿灯通过,但同步到库时报 ERROR 1215。
原因往往是:
- 被引用表
users在目标库中不存在,或引擎不是InnoDB(MyISAM 不支持外键) - 字段类型不严格一致:比如
users.id是BIGINT UNSIGNED,而外键列是BIGINT(符号位不同) - 约束名重复:模型里多个表用了相同外键名(如
fk_user_id),同步时 MySQL 拒绝创建同名约束 -
ON UPDATE/DELETE动作在目标库 SQL mode 下被禁用(例如STRICT_TRANS_TABLES会拒绝ON DELETE SET NULL若字段非空)
为什么“验证通过”后团队仍上线失败?模型没包含运行时依赖
Navicat 模型验证只覆盖 DDL 结构(表、字段、索引、约束),完全不感知以下内容:
- 触发器逻辑:模型里看不到
CREATE TRIGGER,即使触发器里有SIGNAL抛错,验证也无反应 - 存储过程/函数:模型不导入函数体,无法校验其内部是否引用了已删字段
- CHECK 约束表达式合法性:MySQL 5.7 不支持 CHECK,但模型验证不会报错;Navicat 16+ 图形界面又不提供 CHECK 配置入口,容易漏检
- 权限配置:模型不记录用户权限,但上线脚本若含
GRANT,而目标库账号无ALTER ROUTINE权限,就会失败
真正卡点往往不在模型本身,而在模型之外——比如你忘了告诉同事:“这个表上线后必须手动跑一遍 ALTER TABLE ... ADD CONSTRAINT,因为 Navicat 模型根本不认 CHECK”。











