mysql的utf8mb4配置必须在my.cnf中同时设置[client]、[mysql]、[mysqld]三段,缺一则无效;其中[client]和[mysql]设default-character-set=utf8mb4,[mysqld]设character-set-server=utf8mb4及collation-server=utf8mb4_unicode_ci。

my.cnf 中 utf8mb4 配置必须分三处写,漏一处就白配
MySQL 的 utf8mb4 不是“设一个参数就全局生效”的东西。它在客户端、服务端、连接层、表结构四个层面各自独立控制,my.cnf 里只管前三个——但必须同时改 [client]、[mysql]、[mysqld] 三段,缺一不可。
常见错误现象:SHOW VARIABLES LIKE 'character%' 显示 character_set_server 是 utf8mb4,但新创建的表还是 utf8;或者插入 emoji 报错 Incorrect string value: '\xF0\x9F\x98\x80'...。
-
[client]段加default-character-set = utf8mb4:影响所有客户端工具(如 mysql 命令行)的默认连接字符集 -
[mysql]段加default-character-set = utf8mb4:专用于 mysql 命令行客户端自身(和 [client] 略有重叠,但不写可能被忽略) -
[mysqld]段加character-set-server = utf8mb4和collation-server = utf8mb4_unicode_ci:决定新库/新表的默认值,也影响 server 层解析
重启 mysqld 后仍不生效?检查 socket 连接是否绕过配置
Linux 下用 mysql -u root -p 登录时,如果提示 Using a password on the command line interface can be insecure. 之后还连上了,大概率走的是 socket 连接(即本地 Unix socket),此时 [client] 段配置可能未被读取——尤其当 my.cnf 放在非标准路径(如 /etc/my.cnf vs /usr/etc/my.cnf)时。
验证方式:登录后执行 STATUS;,看 “Current client” 行是否显示 via socket;再查 SHOW VARIABLES LIKE 'character_set_client'; 是否为 utf8mb4。
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
- 强制走 TCP 连接测试:
mysql -h 127.0.0.1 -u root -p(注意是127.0.0.1,不是localhost) - 确认配置文件实际加载路径:
mysqld --verbose --help | grep "Default options" - 若用 Docker,确保挂载的
my.cnf被容器内 mysqld 正确识别,且权限为644,否则会静默跳过
已有数据库/表不自动升级,必须手动 ALTER
character-set-server 只影响新创建的数据库和表,对已存在的完全无效。即使你改完配置、重启、新建库,老库里的表依然保持原字符集,连 DESCRIBE table_name 都看不出异常。
典型表现:查询返回乱码、SELECT LENGTH(col) 和 CHAR_LENGTH(col) 不一致、SHOW CREATE TABLE 里显示 DEFAULT CHARSET=utf8。
- 改库:
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; - 改表:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 只改字段(更安全):
ALTER TABLE table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 注意:
CONVERT TO会重建表,大表慎用;生产环境建议先在从库验证
jdbc url 必须显式指定 useUnicode 和 characterEncoding
Java 应用即使 MySQL 服务端全配对了,如果 JDBC URL 没带字符集参数,驱动仍可能用平台默认编码(比如 Windows 上是 GBK),导致存进去是乱码、查出来也是乱码,且错误发生在应用层,SHOW VARIABLES 全绿也查不出问题。
错误示例:jdbc:mysql://localhost:3306/db —— 这个 URL 在 MySQL 8.0+ 默认用 utf8mb4,但旧驱动或某些连接池会 fallback 到 latin1。
- 正确写法:
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=UTC -
useUnicode=true是开关,characterEncoding=utf8mb4才是真正生效的值(注意不是utf8) - Spring Boot 2.4+ 默认启用
useUnicode,但仍需显式写characterEncoding,否则部分场景下仍降级 - 验证方法:在代码里执行
connection.getMetaData().getCharacterSets(),确认返回包含utf8mb4
mysqldump --default-character-set=utf8mb4)、以及任何绕过连接池直连的脚本。这些地方最容易漏,而且一漏就是线上乱码。










