MySQL服务端必须配置utf8mb4字符集与utf8mb4_unicode_ci排序规则,否则emoji和生僻字会截断;需修改my.cnf/my.ini的[mysqld]段并重启,再逐库逐表转换,同时确保连接层三处字符集均为utf8mb4。

MySQL 服务端默认字符集设为 utf8mb4
不改配置文件,CREATE DATABASE 时指定 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 只能保单库,新库、系统库、临时表仍可能掉坑里。必须从服务层统一兜底。
编辑 my.cnf(Linux)或 my.ini(Windows),在 [mysqld] 段下加两行:
[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
注意:不能写成 utf8——MySQL 的 utf8 是阉割版,最多存 3 字节字符,emoji 和部分生僻汉字会截断或报错。
-
init_connect不可靠:对 SUPER 权限用户不生效,且无法影响mysql系统库初始化 - 重启 MySQL 后用
SHOW VARIABLES LIKE 'character_set_server';验证是否生效 - 如果用 Docker,需挂载自定义配置文件,不能只靠
ENV设置
已有数据库和表批量转成 utf8mb4
改完服务端配置只是起点。老库老表的字符集仍是 latin1 或 utf8,字段存了四字节字符会乱码甚至报错 Incorrect string value。
转换分三步,顺序不能错:
- 先改库:
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; - 再改每张表:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 最后单独检查
TEXT/VARCHAR字段长度——utf8mb4单字符最多占 4 字节,若原字段定义为VARCHAR(255)且用了utf8mb4,实际最大字节数是 1020,但 InnoDB 行长度限制仍按 65535 算,极端情况下可能触发Row size too large
别跳过 CONVERT TO:只用 MODIFY COLUMN 改字符集,不会重编码已有数据,旧乱码还是乱码。
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
utf8mb4 下连接层必须同步设置
服务端和表都改了,应用连上去还是存乱码?大概率是客户端没对齐。MySQL 连接有三层字符集:服务端、连接层、结果集。其中连接层(character_set_client / character_set_connection)决定 SQL 文本如何解码。
常见错误场景:
- PHP
mysqli没调set_charset('utf8mb4'),或 PDO DSN 漏了;charset=utf8mb4 - Java JDBC URL 缺
useUnicode=true&characterEncoding=utf8mb4(注意是utf8mb4,不是utf8) - 命令行
mysql -u root -p进去后,SET NAMES utf8mb4;只对当前会话有效,退出即失效
验证连接层是否到位:SHOW VARIABLES LIKE 'character_set%'; 中 client、connection、results 三项必须都是 utf8mb4。
为什么 utf8mb4_unicode_ci 比 utf8mb4_general_ci 更值得选
utf8mb4_general_ci 是 MySQL 5.7 以前的默认排序规则,性能稍快但精度低:它把带重音的字母(如 é 和 e)当成等价,大小写也不严格区分,搜 cafe 可能命中 café,线上查不到数据时容易懵。
utf8mb4_unicode_ci 基于 Unicode 4.0 标准,排序和比较更符合现代语言习惯。MySQL 8.0+ 已默认用 utf8mb4_0900_as_cs(大小写敏感 + 重音敏感),但 5.7/8.0 兼容场景下,utf8mb4_unicode_ci 是最稳的过渡选择。
- 建库建表时不显式指定 collation,会继承 server 层的
collation-server,所以配好collation-server = utf8mb4_unicode_ci很关键 - 已用
general_ci的老表,CONVERT TO时会自动升级 collation,不用额外改 - 如果业务强依赖大小写敏感(比如密码哈希校验),得用
utf8mb4_bin或 MySQL 8.0+ 的_as_cs规则
真正麻烦的是跨版本迁移:MySQL 5.7 的 utf8mb4_unicode_ci 和 8.0 的 utf8mb4_0900_as_cs 排序结果不一致,做主从或备份还原前得核对 collation 是否兼容。

















