根本原因是MySQL客户端连接初始字符集为latin1而非utf8mb4,导致中文字符串被错误解析;需清除SQL文件BOM头、导入时加--default-character-set=utf8mb4参数、建表语句补全DEFAULT CHARSET=utf8mb4。
根本原因不是文件本身损坏,而是 mysql 客户端连接层没用 utf8mb4 解析传入的 sql 内容——哪怕文件是 utf-8 无 bom,只要连接初始字符集是 latin1,中文字符串字面量(如 insert into t values ('张三'))就会被截断或转成问号。
导入前检查 SQL 文件是否带 BOM 头
UTF-8 文件如果开头有 BOM(EF BB BF),MySQL 客户端会把它当不可见字符解析,导致后续 SET NAMES 或建表语句错位,中文字段值直接失效。英文不受影响,所以“英文正常、中文乱码”是典型 BOM 症状。
- 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
导入命令必须显式指定 --default-character-set=utf8mb4
SET NAMES utf8mb4 放在 SQL 文件开头没用——它只影响后续查询,不改变客户端连接建立时的初始字符集。MySQL 默认按 latin1 握手,此时再执行 SET 已晚。
- 正确命令:
mysql --default-character-set=utf8mb4 -u root -p db_name < your.sql - 错误写法:
mysql -u root -p db_name < your.sql(缺参数,必乱码) - 验证连接是否生效:
SELECT @@character_set_client, @@character_set_connection;,两个都应返回utf8mb4 - phpMyAdmin 导入页面里,“文件的字符集”下拉框必须手动选
utf8mb4,不能依赖自动识别
建表语句里漏了 DEFAULT CHARSET=utf8mb4
即使导入过程没报错,如果 CREATE TABLE 语句末尾没写 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci,MySQL 就按数据库默认字符集(常是 latin1)建表,后续插入中文会被静默转成问号。
- 打开 SQL 文件,搜第一个
CREATE TABLE,看结尾有没有DEFAULT CHARSET=utf8mb4 - 没有就补上;注意不是
utf8(那是 MySQL 的阉割版,不支持 emoji 和部分汉字) - 导出时加参数:
mysqldump --default-character-set=utf8mb4 --skip-extended-insert,避免一条 INSERT 包含千行数据导致解析失败 - 目标库的
max_allowed_packet建议调到256M,否则大文件导入中途静默退出
最容易被忽略的是:连接字符串或命令行参数里的 charset 必须是 utf8mb4,而不是 utf8 或 UTF-8;MySQL 服务端配置只是兜底,不解决导入时的实时解析问题。
立即学习“PHP免费学习笔记(深入)”;



















