一、字符集与编码基础 常见字符集
字符集
说明
适用场景
latin1
西欧单字节编码(默认旧版本MySQL)
早期英文环境
utf8
MySQL的“伪UTF-8”,最多3字节,不支持emoji
常见于旧系统
utf8mb4
真·UTF-8,最多4字节,支持emoji
✅ 现代系统推荐
gbk/gb2312
中文编码,2字节
仅限遗留系统
二、MySQL 字符集的层级(四层) 每个层级都可能引起编码不一致导致乱码:
层级
作用范围
查看命令
修复策略
1. 服务器级
默认全局字符集
SHOW VARIABLES LIKE 'character_set_%';
修改配置文件或运行时设置
2. 数据库级
当前数据库默认字符集
SHOW CREATE DATABASE db_name;
ALTER DATABASE db_name CHARACTER SET utf8mb4;
3. 表级
表的默认字符集
SHOW CREATE TABLE table_name;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4;
4. 列级
单列的字符集
SHOW FULL COLUMNS FROM table_name;
ALTER TABLE table_name MODIFY col_name VARCHAR(255) CHARACTER SET utf8mb4;
三、乱码的常见场景与原因
场景
问题来源
示例
客户端插入中文变成“???”
客户端连接编码与服务器不一致
连接未设置 SET NAMES utf8mb4
查询出来乱码
连接层编码不同
JDBC、Python等未声明 charset=utf8mb4
导入SQL文件乱码
文件编码与数据库不符
SQL文件是GBK,数据库是UTF8
网站显示乱码
PHP/HTML未指定正确charset
<meta charset="utf-8"> 缺失或与DB不符
四、修复乱码的通用步骤 1. 确认数据“原始状态” 1 2 SHOW VARIABLES LIKE 'character_set%' ;SHOW VARIABLES LIKE 'collation%' ;
确认数据库、表、列、连接层的编码分别是什么。
2. 确认当前连接编码 1 2 3 SHOW VARIABLES LIKE 'character_set_client' ;SHOW VARIABLES LIKE 'character_set_connection' ;SHOW VARIABLES LIKE 'character_set_results' ;
如不一致可强制指定:
1 2 3 SET NAMES utf8mb4;mysql - uroot - p
3. 检查表和列编码 1 SHOW CREATE TABLE table_name;
如果发现表或列是 latin1、utf8 等旧字符集,可统一转换:
1 ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
注意:CONVERT TO CHARACTER SET 会 重新编码已有数据 ,而不是仅修改元数据。
4. 修复已经“存错”的数据(乱码) 情况1:存进去就是乱码(编码错误写入) 可以导出→转码→重新导入:
1 2 3 4 5 mysqldump --default-character-set=latin1 db > dump_latin1.sql iconv -f latin1 -t utf8 dump_latin1.sql > dump_utf8.sql mysql --default-character-set=utf8mb4 db < dump_utf8.sql
情况2:查询时乱码(连接层问题) 无需修复数据,只需修正连接参数:
1 mysql -uuser -p --default-character-set=utf8mb4
或 JDBC:
1 jdbc :mysql://host/db?useUnicode=true&characterEncoding=utf8mb4
五、永久修复建议 编辑 /etc/my.cnf:
1 2 3 4 5 6 7 8 9 10 [client] default-character-set = utf8mb4[mysql] default-character-set = utf8mb4[mysqld] character-set-server = utf8mb4collation-server = utf8mb4_general_ciinit_connect ='SET NAMES utf8mb4'
重启服务:
1 systemctl restart mysqld
六、修复流程总览 flowchart TD
A[发现乱码问题] --> B[确认客户端字符集]
B --> C[确认MySQL服务端字符集]
C --> D[确认数据库/表/列字符集]
D --> E{数据是否本身被错误编码?}
E -->|否| F[统一配置字符集 utf8mb4]
E -->|是| G[导出→iconv转码→重新导入]
F --> H[测试查询结果]
G --> H
H --> I[更新客户端连接参数]
I --> J[问题解决 ✅]
七、最终建议
目标
建议
新项目
全面采用 utf8mb4
旧系统
分阶段迁移字符集
Web开发
页面、API、数据库统一UTF-8
数据导出导入
总是指定 --default-character-set