不靠。Navicat结构同步预览页生成的SQL是未经数据库解析的中间态语句,不校验语法合法性、不模拟执行计划,且默认缺分号、自动插入可能失效的SET FOREIGN_KEY_CHECKS=0,ENUM变更用MODIFY COLUMN而非安全的CHANGE COLUMN,TEXT类微调未区分业务必要性,需人工核查ALTER锁表模式、NOT NULL字段默认值及引号格式,并优先用转储SQL+diff替代。
结构同步预览页显示的SQL到底靠不靠谱?
不靠。navicat结构同步预览页生成的sql是中间态语句,未经真实数据库解析,也不校验语法合法性,更不会模拟执行计划。它只反映navicat内部比对引擎对差异的“理解”,比如把enum('a','b')扩为enum('a','b','c')时,可能生成modify column而非安全的change column,线上执行会锁表甚至失败。
常见错误现象:预览里看着只有几条ALTER TABLE,点“运行”后却报错ERROR 1064(缺分号)、ERROR 1025(外键约束阻塞)、或ERROR 1175(safe update模式未关)——这些在预览页完全不提示。
- 预览页默认不加语句结尾分号,导出文件也无分号,必须手动补或勾选“每条语句后添加分号”(藏在“高级”选项卡)
-
SET FOREIGN_KEY_CHECKS = 0被自动插入开头,但若目标库有级联更新/删除,这会导致后续ALTER静默失效 - 对
TEXT类字段长度微调(如TEXT→MEDIUMTEXT),预览页不区分是否业务必需,需人工核对源库原始建表语句
怎么拿到真正能走查的同步SQL?
别直接信预览页右上角的“导出SQL文件”按钮。它导出的是未清洗的中间结果,注释冗余、语句不完整、缺少必要前置设置。
正确路径是:先用“转储SQL文件”导出源库和目标库各自结构,再人工比对+生成变更脚本;若必须用结构同步,按以下步骤操作:
- 右键源库 →「转储SQL文件」→ 勾选「结构」+「兼容模式:MySQL 5.7」+「导出外键」+「添加DROP语句」
- 同样操作导出目标库结构,用
diff工具比对两个文件,聚焦CREATE TABLE和ALTER TABLE块 - 若坚持用结构同步,进入预览页后,点击「编辑脚本」→ 删除开头的
SET FOREIGN_KEY_CHECKS = 0和SET SQL_MODE(由DBA统一管控)→ 手动补全每行末尾; - 对所有
ENUM字段变更,替换MODIFY COLUMN为CHANGE COLUMN语法,避免重建字段引发长事务
为什么“对象信息 → DDL”不能替代结构同步预览?
SHOW CREATE TABLE输出的是当前表的最终定义,而结构同步预览展示的是“从目标库状态到源库状态所需执行的操作”。二者用途完全不同。
例如:目标库表字段顺序是a,b,c,源库是c,a,b,对象信息 → DDL只显示源库的CREATE TABLE语句;但结构同步预览会生成三条ALTER TABLE ... MODIFY COLUMN来调序——而这在MySQL里实际无效(字段顺序不影响功能),纯属Navicat比对逻辑缺陷。
- 当看到预览里大量
MODIFY COLUMN调整VARCHAR长度(如100→191),先确认是不是源库建表时就写了utf8mb4导致索引长度限制触发的被动扩容 - 若预览出现
DROP INDEX后立刻CREATE INDEX,说明Navicat把索引重命名识别为“删除+新建”,需人工合并为RENAME INDEX - 对含反引号的字段名(如
`user name`),预览页会保留,但部分旧版MySQL客户端不支持,走查时要检查目标环境兼容性
执行前必须人工验证的三个硬指标
结构同步预览页不校验任何东西,最终上线前必须盯死这三点,否则就是生产事故。
第一看ALTER TABLE是否含LOCK=NONE或ALGORITHM=INPLACE——没写就是默认LOCK=DEFAULT,大表会锁死整个表;第二看所有ADD COLUMN是否都带NOT NULL且无DEFAULT值,MySQL 8.0+会直接拒绝;第三看ENUM/SET字段新增值是否在字符串内用了单引号('new_val'),双引号会被MySQL当作标识符报错。
最易被忽略的是:Navicat对分区表、JSON字段、隐藏索引等8.0+特性,在5.7兼容模式下会静默忽略或降级处理,预览页完全不提示——得靠导出的SHOW CREATE TABLE原文逐字比对。











