必须同时修改[client]、[mysql]、[mysqld]三段:[client]和[mysql]设default-character-set=utf8mb4,[mysqld]设character-set-server=utf8mb4及collation-server=utf8mb4_0900_ai_ci;仅改[mysqld]无效,重启后须验证四个character_set变量全为utf8mb4。

必须同时修改 my.cnf(Linux/macOS)或 my.ini(Windows)中的 [client]、[mysql]、[mysqld] 三段,缺一不可;只改 [mysqld] 段的 character-set-server 几乎必然失效。
配置文件里哪三段必须改、怎么写
MySQL 字符集不是“设一个就全局生效”的开关,它在客户端工具、命令行连接、服务端默认值三个层面各自读取不同配置段。漏掉任意一段,SHOW VARIABLES LIKE 'character%' 就会暴露问题。
-
[mysqld]段加两行:character-set-server = utf8mb4collation-server = utf8mb4_0900_ai_ci(MySQL 8.0+ 推荐,别用utf8mb4_unicode_ci,除非要兼容老应用) -
[client]段加:default-character-set = utf8mb4(影响mysqldump、mysqladmin等所有客户端工具) -
[mysql]段加:default-character-set = utf8mb4(专管mysql -u root -p命令行客户端自身;不写它,连上去后character_set_client很可能还是utf8)
Windows 用户注意路径是 C:\ProgramData\MySQL\MySQL Server X.X\my.ini(不是 Program Files 目录);Docker 必须挂载自定义 my.cnf 到容器内 /etc/mysql/my.cnf,且权限必须是 644,否则静默跳过。
重启后必须验证四个变量全为 utf8mb4
只改配置不验证,等于白干。连接 MySQL 后执行:SHOW VARIABLES LIKE 'character%';
必须全部满足:
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
character_set_client = utf8mb4character_set_connection = utf8mb4character_set_results = utf8mb4character_set_server = utf8mb4
任一值仍是 utf8(即 utf8mb3)或 latin1,说明配置没加载成功——常见原因是段落写错位置(比如塞进 [mysqld_safe])、文件路径不对、或被其他同名配置文件覆盖。Linux 下用 mysql -h 127.0.0.1 -u root -p 强制走 TCP 连接测试,可绕过 socket 连接不读 [client] 段的坑。
已有数据库和表不会自动升级,必须手动 ALTER
character-set-server 只影响新创建的数据库和表,对已存在的完全无效。哪怕你重启后新建库,老库里的表依然保持原字符集,DESCRIBE table_name 看不出异常,但插入 emoji 会报 Incorrect string value: '\xF0\x9F\x98\x80'。
- 先改库:
ALTER DATABASE `your_db` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; - 再改每张表:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;(必须用CONVERT TO,只MODIFY COLUMN不会重编码已有数据)
特别注意:TEXT/VARCHAR 字段长度在 utf8mb4 下实际占用字节数翻倍,原 VARCHAR(255) 在 InnoDB 中最多占 1020 字节,可能触发 Row size too large 错误,必要时需缩减字段长度。
应用连接层仍需显式指定 charset
即使服务端和连接层全配对了,PHP、Python、Java 等应用连接 MySQL 时,仍需在 DSN 或连接参数中显式声明:
PHP PDO:charset=utf8mb4
Python PyMySQL:charset='utf8mb4'
Java JDBC:characterEncoding=utf8mb4
不写这个,某些驱动会 fallback 到旧字符集,尤其在连接复用或连接池场景下,容易出现“有时正常、有时乱码”的隐蔽问题。










