MySQL字符集必须统一为utf8mb4,排序规则优先选utf8mb4_0900_ai_ci(8.0+)或utf8mb4_unicode_ci(兼容场景),以完整支持emoji、生僻字及多语言;需全链路(服务器、库、表、列、连接)显式配置并验证,避免乱码与查询异常。

MySQL 字符集与排序规则必须统一为 utf8mb4 + utf8mb4_0900_ai_ci(MySQL 8.0+)或 utf8mb4_unicode_ci(5.7/8.0 兼容场景),这是当前生产环境最稳妥、最通用的选择。其他组合容易引发乱码、查询异常或国际化支持缺陷。
字符集选 utf8mb4 是硬性前提
MySQL 的 utf8 实际只支持最多 3 字节 Unicode 字符,无法存储 emoji(如 ?、??)、生僻汉字(如 “?”)、越南语重音字等。而 utf8mb4 完整支持 4 字节 UTF-8 编码,是唯一能覆盖全部 Unicode 字符的选项。
- 不要用
latin1或gbk:前者中文直接变问号,后者虽省内存但不兼容英文以外多语言系统 - 新建库表时显式声明,不依赖服务器默认值——避免迁移或跨环境部署时意外回退
- 已有数据若已用
utf8存储中文,需先确认是否实际乱码;若未乱码,说明内容恰好落在 BMP 平面,但仍建议升级以防后续插入 emoji 失败
排序规则优先选 utf8mb4_0900_ai_ci(MySQL 8.0+)
该规则基于 Unicode 9.0 标准,同时做到:不区分大小写(_ci)+ 不区分重音(_ai),兼顾准确性与实用性。例如:'café' 和 'cafe' 在 _ai_ci 下视为相等,符合多数 Web 应用搜索预期。
-
utf8mb4_general_ci已过时:排序精度低(如忽略某些语言特殊规则),MySQL 5.7 起不再推荐 -
utf8mb4_bin仅用于需要严格二进制比对的场景(如密码哈希校验),日常字段查询会因大小写敏感导致漏匹配 - 中文场景无需专用
_zh_*规则:标准_ai_ci对汉字排序已足够合理,且更利于未来拓展法语、西班牙语等
配置要覆盖全链路,不能只设一处
字符集生效依赖“客户端→连接→数据库→表→列”五层一致。任一环节脱节都会导致乱码或隐性错误。
- 服务器级(
my.cnf):设置character-set-server=utf8mb4和collation-server=utf8mb4_0900_ai_ci,并加init_connect='SET NAMES utf8mb4' - 建库建表时显式指定:
CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; - 已有表转换用
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;(操作前务必备份) - 应用连接参数必须声明编码:JDBC 加
?useUnicode=true&characterEncoding=UTF-8,Python PyMySQL 指定charset='utf8mb4',PHP PDO 设置PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
验证与排查要查到具体层级
不能只看 SHOW VARIABLES LIKE 'character_set%',那只是服务器和连接层。真正影响数据的是字段级定义。
- 查库默认:
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'your_db'; - 查表结构:
SHOW CREATE TABLE your_table;看DEFAULT CHARSET和字段COLLATE - 查字段详情:
SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'your_table'; - 若发现某字段仍是
utf8或latin1,即使库和表已改,该字段仍会按旧规则存储和比较


















