执行 SHOW VARIABLES LIKE 'character\_set%' 返回的关键编码项是 character\_set\_client、character\_set\_connection 和 character\_set\_results,三者需一致以避免乱码。

SHOW VARIABLES LIKE 'character\_set%' 返回哪些关键编码项
执行 SHOW VARIABLES LIKE 'character_set%' 会列出 MySQL 当前所有字符集相关变量,但真正影响「当前连接」行为的只有三个:
character_set_client(客户端发来的数据按什么编码解析)
character_set_connection(SQL 解析和内部转换用的中间编码)
character_set_results(结果集返回给客户端时用的编码)
这三个值一致才不容易乱码;不一致时,MySQL 会在它们之间自动转码,但转码失败或配置错位就会丢字符。
为什么 SET NAMES utf8mb4 比逐个 SET 更可靠
SET NAMES utf8mb4 是一条快捷命令,它等价于同时执行:
SET character_set_client = utf8mb4SET character_set_connection = utf8mb4SET character_set_results = utf8mb4
手动逐个 SET 容易漏掉某一项,尤其 character_set_connection 常被忽略——它不显示在客户端连接初始化日志里,但直接影响 SQL 字符串字面量(比如 WHERE name = '中文')的解析结果。
连接建立后改编码,旧查询结果不受影响
修改 character_set_results 只影响后续查询的返回格式,不会重刷之前已执行过的语句结果。常见误操作是:
- 先查了一条含中文的记录,看到乱码
- 然后执行 SET NAMES utf8mb4
- 再查一次,发现还是乱码 → 其实第一次查的结果缓存在客户端,没刷新
- 正确做法是重新执行查询,或用 SELECT ... 显式再取一次
另外,如果客户端本身不支持 utf8mb4(比如老版本 MySQL 命令行工具未加 --default-character-set=utf8mb4 参数),光在服务端 SET 也没用。
my.cnf 里 default-character-set 已被弃用,别再配它
MySQL 5.5+ 中,[client] 段里的 default-character-set 已被忽略,必须改用 charset:
[client] charset = utf8mb4否则即使服务端设对了,命令行客户端连上来默认还是
latin1。驱动层面同理:Java 的 JDBC URL 要加 useUnicode=true&characterEncoding=utf8mb4,Python 的 PyMySQL 要显式传 charset='utf8mb4' 参数——服务端的 SHOW VARIABLES 看不出这些客户端侧的缺失。


















