MYSQL40 是唯一合理选择,它兼容 MySQL 5.0 至 8.0 基础语法并保留视图、存储过程等结构,而 MYSQL323 会破坏外键、字符集和排序规则;勾选“添加 SET SQL_MODE”可冻结导出时的宽松模式以避免导入中断;utf8mb4_0900_as_cs 等新排序规则需手动替换;DEFINER 报错须在导出时禁用或事后正则清除。
导出时选 MYSQL40 还是 MYSQL323?
绝大多数跨版本迁移场景下,mysql40 是唯一合理选择。它能覆盖 mysql 5.0 到 8.0 的基础语法兼容,同时保留视图、存储过程等关键结构(mysql323 会强制禁用这些,导致导出文件缺失功能)。
只有当你明确目标库是 MySQL 3.23 或 4.0(已淘汰近 20 年),才考虑 MYSQL323;否则选它只会让导出文件变“残废”,比如把 ENGINE=InnoDB 强制降成 TYPE=MyISAM,还删掉所有外键约束声明。
-
MYSQL40不改表结构,只屏蔽高版本语法(如窗口函数注释、JSON 类型声明) -
MYSQL323会主动破坏结构:删FOREIGN KEY、砍CHARSET声明、把utf8mb4全换成utf8 -
phpMyAdmin 5.0+ 默认不显示
MYSQL323选项,需手动在 config 中启用——这本身就是个信号
勾选“添加 SET SQL_MODE”为什么不能省?
这个选项不是锦上添花,而是防止导入时因模式差异直接中断的关键开关。比如目标库启用了 STRICT_TRANS_TABLES,而导出文件里有 INSERT INTO t VALUES (NULL)(对非空字段插 NULL),没这句 SET SQL_MODE 就会报错退出。
它生成的语句类似:SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES',把导出时的宽松模式“冻结”进文件开头,让导入环境按原样执行。
- 不勾选 → 导入时用目标库默认
sql_mode,极易触发ERROR 1364(字段无默认值)、ERROR 1048(列不能为空) - 勾选后仍报错 → 说明错误来自语法本身(如
JSON字段),不是模式问题,得另处理 - 该设置只影响 SQL 执行行为,不改变字符集或排序规则,别指望它解决
Unknown collation
为什么导出后还是报 utf8mb4_0900_as_cs 错误?
MYSQL40 兼容模式根本不管排序规则(collation),它只处理语法关键字和结构。所以 utf8mb4_0900_as_cs 这种 MySQL 8.0 新增的 collation 会被原样保留,导入到 5.7 就报 Unknown collation。
必须手动替换:目标库是 5.7 就统一换成 utf8mb4_unicode_ci;是 5.6 或更老,就得降级成 utf8_general_ci,并同步把 CHARSET=utf8mb4 改成 CHARSET=utf8。
- 用
sed -i 's/utf8mb4_0900_as_cs/utf8mb4_unicode_ci/g' dump.sql(Linux/macOS) - Windows 上用 PowerShell:
(Get-Content dump.sql) -replace 'utf8mb4_0900_as_cs', 'utf8mb4_unicode_ci' | Set-Content dump.sql - 别用编辑器“全部替换”跳过注释行——有些注释里也混着这个字符串,替错了会破坏备份完整性
DEFINER 报错和兼容模式无关,但常被一起处理
DEFINER=`user`@`host` 是权限元数据,不是语法,所以选 MYSQL40 或勾选 SET SQL_MODE 都拦不住它。MySQL 5.7+ 默认记录 DEFINER,而目标库要么没对应账号,要么开了 NO_DEFINER 模式。
最稳做法是导出时就关掉:在「自定义」→「对象创建选项」里取消勾选「添加 DEFINER 和 SQL SECURITY」。如果已导出,就全局删掉 DEFINER=`.*?`@`.*?`(正则),注意触发器里的 DEFINER phpMyAdmin 默认不处理,得单独扫一遍。
- 删完 DEFINER 后,如果还报
This function has none of DETERMINISTIC...,说明函数缺特性声明,得手动补READS SQL DATA - 别试图用
SET GLOBAL log_bin_trust_function_creators = 1绕过——这是安全风险,且在云数据库上通常不可调 - phpMyAdmin 的“忽略 DEFINER”选项对事件(EVENT)无效,事件必须手动删或改用
mysqldump --skip-definer
MYSQL40 + SET SQL_MODE 只解决一半问题;剩下那半(排序规则、DEFINER、JSON 字段、加密属性)得靠人工筛查或脚本清洗,漏掉任意一项都可能让导入卡在中间。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











