Navicat 17「模型同步到数据库」是暴力覆盖而非无损推送,会DROP再CREATE表、不校验字段差异与数据保留;安全方式应使用「结构同步」并人工核验SQL、版本兼容性及字符集等细节。
navicat 17 的「模型同步到数据库」不是无损推送,而是暴力覆盖 —— 除非你全程绕开它,改用人工校验 + 差异 sql 手动执行。
为什么不能点「同步到数据库」按钮直接推生产
这个按钮的行为是:先 DROP TABLE 目标表,再 CREATE TABLE 新结构。它不比对字段级差异,不保留数据,也不检查外键依赖或从库延迟。哪怕你只在模型里改了一个默认值,它也会把整张带业务数据的表清空重建。
- 执行不可中断、不可撤回,日志里只显示“成功/失败”,不输出实际执行的
SQL - 若模型中某表没设主键,但生产库该表已有主键,同步后主键被删,后续插入可能违反唯一约束
- 模型设为 MySQL 8.0,但连接的是 5.7 实例,生成的
JSON字段语法会直接报错,Navicat 不做版本适配
真正安全的路径:用「结构同步」代替「模型同步」
结构同步(工具 → 结构同步)才是面向生产环境的可控方式,它基于两个物理数据库做差异比对,而非模型与库之间单向覆盖。
- 必须手动确认源库(测试库)和目标库(生产库)的 MySQL 版本兼容性,比如
GENERATED COLUMN在 5.7 不可用 - 对比后,默认勾选全部变更项,但你要主动取消:
DROP COLUMN、DROP INDEX、DROP TABLE—— 这些在生产上基本等同于事故 - 点击「部署」后务必点开生成的
SQL脚本,检查是否有MODIFY COLUMN ... NOT NULL这类语句;如果对应列存在空值,执行必然失败 - 字符集必须显式声明:新增字段若没写
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs,会继承库级默认值,而那个默认值可能和旧列不一致,导致JOIN或ORDER BY出错
模型只用于设计和协作,不是部署管道
Navicat 17 的 ER 模型设计器是只读设计载体,它不执行任何 DDL。所谓“同步模型到数据库”,本质是生成一套完整建表脚本再暴力执行 —— 这适合初始化空库,不适合已有数据的生产环境。
- 右键表 →「复制为 SQL」只导出单表语句,漏掉外键、索引、注释,不能直接用于生产
- 「文件 → 生成 SQL 文件」虽能勾选外键和索引,但默认不含
IF NOT EXISTS,表已存在时会报错 - 模型中表名写成
user,但生产库实际是User(大小写敏感),生成的外键语句将指向不存在的父表 - 团队共享模型时,
.nmodel文件本身不包含执行上下文,无法还原权限、存储过程、触发器等元信息
最易被忽略的一点:结构变更是否生效,不能只信 Navicat 的「运行成功」提示。上线后必须立刻执行 SHOW CREATE TABLE 和 SHOW INDEX FROM,确认字段顺序、默认值、索引冗余、时间类型自动补的 CURRENT_TIMESTAMP 是否符合预期 —— 很多问题在第一波查询慢日志里才暴露出来。


















