出现incorrect string value错误,说明客户端、连接层、表字段三者未对齐到utf8mb4;必须通过show variables like 'character_set%'确认character_set_client、connection、results全为utf8mb4,改表须用convert to而非仅设表级字符集,且应用连接参数必须显式指定charset=utf8mb4。

直接结论:出现 Incorrect string value: '\xE6\x88\x91' 这类错误,说明客户端、连接层、表字段三者没对齐到 utf8mb4,不是“数据库不支持中文”,而是链路断在某一处。
查清当前实际生效的字符集配置
别信 my.cnf 或建库语句,运行时可能被覆盖。连上 MySQL 后立刻执行:
SHOW VARIABLES LIKE 'character_set%';
重点关注这三项是否全为 utf8mb4:
-
character_set_client:你发 SQL 时,MySQL 认为你用的编码 -
character_set_connection:连接层转码用的中间编码,必须和 client 一致 -
character_set_results:返回结果时用的编码
只要有一个是 latin1 或旧版 utf8(即 utf8mb3),就说明链路断了。
改表字段必须用 CONVERT TO,不能只改表级声明
ALTER TABLE table_name CHARACTER SET utf8mb4 这种写法只改元数据,字段实际存储仍按旧编码,无效。
真正生效的是:
ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
但要注意:
- 大表会锁表、重建索引、临时磁盘空间翻倍,务必选低峰期
- 若字段有全文索引,
utf8mb4下单列索引长度上限是 767 字节,需配合innodb_large_prefix=ON和ROW_FORMAT=DYNAMIC - 只想改某列(比如
TEXT类型),用MODIFY更可控:ALTER TABLE t MODIFY content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
但必须重写完整字段定义,否则可能丢NOT NULL或DEFAULT约束
连接层不设 charset=utf8mb4,前面全白搭
即使数据库、表、字段全设成 utf8mb4,只要应用连接没声明字符集,MySQL 仍按 latin1 解析请求——这是最常被忽略的一环。
不同场景写法不同:
- PHP PDO:
mysql:host=localhost;charset=utf8mb4必须写进 DSN - Java JDBC:
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8mb4,注意&要转义,驱动建议用 8.0+ - 命令行 mysql 客户端:
mysql --default-character-set=utf8mb4 -u root -p,否则默认用latin1 - Navicat:右键连接 →「编辑连接」→「高级」→ 勾选「使用 MySQL 字符集」并选
utf8mb4
漏掉任何一处,character_set_client 就不会变成 utf8mb4,后续所有环节都跟着错。
SQL 文件导入前必须确认真实编码和连接参数
编辑器显示“UTF-8”不等于文件真是 UTF-8。Windows 上 VS Code 默认可能存成 UTF-8 with BOM,MySQL 会把 BOM 当非法字符报错;Linux/macOS 下用 file -i dump.sql 看真实编码。
若文件是 GBK 编码,不能直接导入:
- 用
iconv -f gbk -t utf8mb4 dump.sql > dump_utf8.sql转换 - 导入时必须加参数:
mysql --default-character-set=utf8mb4 -u root -p db_name - 如果用
source方式导入,也要先在连接后执行:SET NAMES utf8mb4;
容易被忽略的是:命令行参数 --default-character-set=utf8mb4 必须放在 -u 前面,顺序错了就不起作用。











