MySQL低版本导入高版本导出SQL报错的四大原因及解决:字符序不兼容需替换、生成列定义缺失需补全、自定义函数未导出需勾选、DEFINER权限报错需删除;务必按目标版本逐项核对。
导出时提示“Unknown collation: 'utf8mb4_0900_ai_ci'”
这是目标 mysql 版本低于 8.0(尤其是 5.7)时最常遇到的报错,因为 utf8mb4_0900_ai_ci 是 mysql 8.0 默认字符序,5.7 不识别。
不能直接删掉或留空 collation,否则建表可能失败或排序行为异常。稳妥做法是按目标版本替换:
- 若导入目标是 MySQL 5.7:全局替换
utf8mb4_0900_ai_ci→utf8mb4_unicode_ci - 若目标是 MySQL 5.6 或更老:必须同时降级字符集和排序规则:
CHARSET=utf8mb4改为CHARSET=utf8,再把所有utf8mb4_0900_ai_ci替换为utf8_general_ci - Linux/macOS 可用:
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' dump.sql - Windows PowerShell:
(Get-Content dump.sql) -replace 'utf8mb4_0900_ai_ci', 'utf8mb4_unicode_ci' | Set-Content dump.sql
导出含 GENERATED ALWAYS AS 列的表结构丢失
旧版 phpMyAdmin(≤ 4.9.x)解析 MySQL 5.7+ 元数据不完整,即使勾选了 CREATE TABLE,导出的 SQL 里也会漏掉 GENERATED ALWAYS AS (expr) STORED 子句,导致导入时报 unknown column 'xxx' in 'field list'。
关键不是“导出有没有数据”,而是“列定义是否完整”。验证方式很简单:导出后执行 SHOW CREATE TABLE `table_name` 对比原表,看生成列行是否存在。
- 升级到 phpMyAdmin ≥ 5.0.0 是根本解法(5.2.3 已稳定支持)
- 临时补救:手动在导出 SQL 中找到
CREATE TABLE语句,在对应列定义后补上完整语法,例如:`hash_id` VARCHAR(32) GENERATED ALWAYS AS (MD5(`id`)) STORED - 注意括号嵌套和分号位置——补错一个括号,整条语句就失效
导入时卡在 “FUNCTION xxx does not exist”
如果生成列或触发器里调用了自定义函数(如 GENERATED ALWAYS AS (my_hash(id)) STORED),而导出文件没带函数定义,MySQL 5.7+ 会直接中断导入。
立即学习“PHP免费学习笔记(深入)”;
phpMyAdmin 默认不导出函数,哪怕你勾了“仅数据”或“结构”,也得主动指定。
- 导出前,在左侧数据库页点「导出」→「自定义」→ 展开「对象」→ 勾选
Functions - 确保函数定义块(
CREATE DEFINER=... FUNCTION `my_hash`...)出现在CREATE TABLE之前 - 若函数依赖其他函数、视图或过程,需一并勾选导出,否则仍会失败
- MySQL 5.7 要求函数声明特性(
READS SQL DATA等),旧版导出缺这个,需手动在RETURNS后补上
导出文件里有 DEFINER 和 SQL SECURITY 报错
旧版 phpMyAdmin 导出存储过程、视图、函数时默认保留 DEFINER=`user`@`host` SQL SECURITY DEFINER,而目标库若启用了二进制日志或 strict 模式,会拒绝执行,报权限错误。
这不是目标库权限配错了,是语句本身被 MySQL 主动拦截。
- 最简方案:全局删除
DEFINER=`[^`]*`@`[^`]*`(正则匹配,注意转义) - Linux/macOS:
sed -i 's/DEFINER=`[^`]*`@`[^`]*`//g' dump.sql - Windows PowerShell:
(Get-Content dump.sql) -replace 'DEFINER=`[^`]*`@`[^`]*`', '' | Set-Content dump.sql - 删完后加一行
SET NAMES utf8mb4;在文件开头,防中文乱码



















