字符集与排序规则是什么
字符集决定能用哪些字符、每个字符占几字节;排序规则决定比较与排序的语义(大小写、重音是否敏感)。乱码和 emoji 写不进去,根因几乎都是链路不一致:客户端、连接、结果、库、表这五层要统一到 utf8mb4。MySQL 里写的 utf8 实际是 utf8mb3,最多 3 字节,存不了 emoji。
基本信息
| 关键参数 | character_set_client / connection / results / database / server |
|---|---|
| 排序参数 | collation_server / collation_connection / collation_database |
| 推荐组合 | utf8mb4 加 utf8mb4_0900_ai_ci(8.0 默认) |
| 配置位置 | 服务端 [mysqld],客户端 [client] default-character-set |
| 版本差异 | 8.0 默认 utf8mb4,5.7 默认 latin1 |
典型使用场景
- 新建库表:从服务端到建表语句统一指定 utf8mb4,避免后续迁移
- 老库迁移:逐个库表核对字符集,5.7 迁来的实例必查
- emoji 写入报错:确认列字符集与连接字符集是否支持 4 字节
- 中文乱码:检查客户端发送编码与连接的转换是否一致
- 排序结果异常:确认排序规则的大小写与重音敏感度是否与业务预期一致
- 跨实例同步:两边字符集不同会导致数据截断或比较结果不同
查看与统一
查看与统一
SHOW VARIABLES LIKE 'character_set%'; -- 链路各层字符集
SHOW VARIABLES LIKE 'collation%'; -- 排序规则
SHOW CREATE TABLE app.user\G -- 看表与列的字符集
SHOW FULL COLUMNS FROM app.user; -- 逐列核对 collation
ALTER DATABASE app CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE app.user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- 配置文件(重启生效)
-- [mysqld]\n-- character-set-server = utf8mb4\n-- collation-server = utf8mb4_0900_ai_ci\n-- [client]\n-- default-character-set = utf8mb4链路参数读法
| 参数 | 含义 | 异常表现 |
|---|---|---|
| character_set_client | 客户端发送语句的编码 | 与实际编码不符时中文变问号 |
| character_set_connection | 服务端转换后使用的编码 | 转换丢字时字符串被截断 |
| character_set_results | 返回结果给客户端的编码 | 查询结果出现乱码方块 |
| character_set_database | 默认库的字符集 | 建表未指定列字符集时会继承它 |
| collation_connection | 当前连接比较字符串的规则 | 影响 WHERE 与 ORDER BY 的大小写敏感 |
MySQL 的 utf8 实际是 utf8mb3,最多 3 字节,存不了 emoji;8.0 默认 utf8mb4,5.7 默认 latin1,老库迁移必查。
8.0 默认 utf8mb4_0900_ai_ci 与 5.7 常用的 utf8mb4_general_ci 在重音和排序上存在差异,从 5.7 升级后同一 ORDER BY 的结果可能变化,升级前应在测试库比对。
连接层字符集通常由驱动设置(JDBC 用 characterEncoding、PHP 用 set names),服务端的 character_set_server 只决定新建库表的默认值;排查先看 character_set_client 与 character_set_connection 是否都是 utf8mb4,再往库表层查。