MySQL乱码本质是客户端、连接层、表结构字符集不一致,需统一为utf8mb4并正确配置各层编码。

MySQL字符集错误导致的乱码,本质是客户端、连接层、表结构三者字符集不一致。最常见的是插入时用UTF8mb4,但建表用latin1,或连接未声明编码,结果存进去就是问号或 Mojibake(如“æäº›æå”)。
检查当前各层字符集设置
登录MySQL后执行以下命令,重点关注client、connection、database、results、server、system这7个变量:
- SHOW VARIABLES LIKE 'character_set%'; —— 查看所有字符集相关变量
- SHOW VARIABLES LIKE 'collation%'; —— 查看排序规则,需与字符集匹配(如 utf8mb4_unicode_ci 对应 utf8mb4)
- SHOW CREATE TABLE 表名; —— 确认表和字段实际使用的字符集,不是“看着像UTF8”就安全
统一字符集到utf8mb4(推荐方案)
utf8mb4 支持完整Unicode(含emoji、生僻汉字),是MySQL 5.5.3+官方推荐的UTF8实现。不要用已废弃的utf8(实际是utf8mb3)。
character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
- 在[client]和[mysql]段也加上:default-character-set = utf8mb4
- 重启MySQL服务生效
- 对已有库/表升级:先改库,再改表,最后改字段(顺序不能错)
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
确保连接时指定正确编码
即使服务端设好了,客户端连接没声明,照样乱码。不同场景处理方式不同:
- 命令行mysql客户端:启动时加参数 -D database_name --default-character-set=utf8mb4,或连接后立刻执行 SET NAMES utf8mb4;
- PHP mysqli:连接后调用 $mysqli->set_charset("utf8mb4");
- Python PyMySQL:创建连接时传参 charset='utf8mb4'
- JDBC URL:在连接串末尾加上 ?characterEncoding=utf8mb4&serverTimezone=UTC
修复已乱码的数据(谨慎操作)
如果数据已存为乱码(比如原应是中文,却显示为“æ—类二进制垃圾),不能简单ALTER CONVERT。需按“错误编码 → 正确编码”双重转换还原:
- 先确认当前字段存的是什么编码错觉(常见:latin1存了utf8字节流)
- 把字段临时转成binary,再以正确字符集重新解读
- 示例(原用latin1存utf8内容,现恢复):
ALTER TABLE t MODIFY COLUMN c VARBINARY(100); ALTER TABLE t MODIFY COLUMN c VARCHAR(100) CHARACTER SET utf8mb4;
操作前务必备份!这种修复依赖原始错误路径,误判会导致数据永久损坏。










