根本原因是导出时没对齐源库字符集,而导入时又没强制客户端用对应编码解析;导出前未执行SET NAMES utf8mb4或配置未生效,导致SQL文件缺失/!40101 SET NAMES utf8mb4/声明,且导入时未加--default-character-set=utf8mb4参数。
根本原因是导出时没对齐源库字符集,而导入时又没强制客户端用对应编码解析——不是文件本身“坏了”,是 mysql 连接握手阶段就按错的字符集读取了 sql 里的中文和建表语句。
导出前没设好源库连接字符集,SQL 文件头缺 SET NAMES utf8mb4
phpMyAdmin 导出逻辑依赖当前会话的 character_set_client。如果导出前没手动执行 SET NAMES utf8mb4,或数据库配置里 init_connect 没生效,导出的 SQL 就不会带字符集声明,或者只写 SET NAMES utf8(注意不是 utf8mb4)。
- 打开导出的 SQL 文件,搜前三行:没有
/*!40101 SET NAMES utf8mb4 */就说明导出源头没对齐 - 导出页面的 “格式特定选项” 里勾选 “Add SET NAMES statement” 不够,它只加
SET NAMES utf8,得手动在 phpMyAdmin 的 SQL 窗口先运行SET NAMES utf8mb4再点导出 - 如果源库是 MySQL 5.7+ 且已用
utf8mb4,但导出文件里建表语句还写着DEFAULT CHARSET=utf8,那一定是导出时连接字符集错了
导入命令漏了 --default-character-set=utf8mb4
mysql -u root -p db_name 这种写法默认按 <code>latin1 握手,哪怕 SQL 文件是 UTF-8 无 BOM,里面的 '张三' 也会被截成乱码或问号——SET NAMES utf8mb4 在文件里再靠前也救不回来,因为客户端解析 SQL 字符串时已经错了。
- 必须显式加参数:
mysql --default-character-set=utf8mb4 -u root -p db_name - 验证是否生效:导入后立刻执行
SELECT @@character_set_client, @@character_set_connection;,两个都得是utf8mb4 - 别信 phpMyAdmin 导入页的 “自动检测字符集”,它常把 UTF-8 BOM 文件识别成
binary,手动选utf8mb4才靠谱
SQL 文件带 BOM 头,导致 SET NAMES 或建表语句错位
UTF-8 文件开头有 BOM(EF BB BF)时,MySQL 客户端会把它当不可见字符吞掉,结果 SET NAMES 变成 SET NAMES,整行失效;或者建表语句的 CREATE TABLE 被顶到第二行,触发语法错误。
- Linux/macOS 下检查:
hexdump -C your.sql | head -n 1,看开头是不是ef bb bf - 删 BOM:
sed -i '1s/^\xEF\xBB\xBF//' your.sql(单引号不能省) - Windows 下用 VS Code 打开 → 右下角点编码名 → “Save with Encoding” → 选 “UTF-8”(明确是“无 BOM”);别点“另存为 UTF-8”,很多编辑器默认仍带 BOM
目标库版本太低,不认 utf8mb4 字符集声明
MySQL 5.5.3 之前压根不支持 utf8mb4,导入时遇到 DEFAULT CHARSET=utf8mb4 或 COLLATE=utf8mb4_unicode_ci 就直接报 #1115 - Unknown character set: 'utf8mb4',连语法解析都过不去。
立即学习“PHP免费学习笔记(深入)”;
- 先查目标库版本:
SELECT VERSION(); - 若低于 5.5.3,只能二选一:升级 MySQL,或手动替换 SQL 文件里的所有
utf8mb4为utf8(注意只是临时 workaround,emoji 和部分生僻字会丢) - 别只换
CREATE DATABASE行,要全局搜utf8mb4,包括CREATE TABLE、ALTER TABLE、COLLATE后面的值
最容易被忽略的是:字符集问题从来不是单点故障,而是连接层、文件层、服务层三者没对齐。哪怕 SQL 文件内容完全正确,只要客户端连接初始字符集不对,中文就注定变问号——这个底层机制,比改文件编码或调 php.ini 更优先。



















