mysql数据库中文乱码问题通常是由于字符集设置不一致导致的,涉及服务端、客户端、数据库、表、字段等多个层级的字符集配置,只要保证全链路字符集统一,就能解决大部分乱码问题。

常见乱码原因
中文乱码的核心原因是数据在写入、存储、读取过程中使用的字符集不一致,常见的场景包括:
- 创建数据库或表时未指定字符集,使用了默认的latin1等非中文兼容字符集
- 客户端连接mysql时未指定正确的字符集,导致传输过程中编码转换错误
- mysql服务端默认字符集配置为非utf8系列,和客户端字符集不匹配
- 字段级别的字符集和表、数据库字符集不一致
具体解决方法
1. 创建数据库时指定字符集
新建数据库时直接指定字符集为utf8mb4,这是目前最推荐的中文兼容字符集,支持所有emoji和生僻字,避免使用utf8(mysql中的utf8是阉割版,最多支持3字节字符)。
-- 创建数据库时指定字符集和排序规则 CREATE DATABASE test_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
2. 修改已有数据库和表的字符集
如果已经存在乱码问题的数据库或表,可以通过ALTER语句修改字符集,注意修改表字符集会自动同步字段的字符集,但如果之前字段有单独设置字符集,需要单独处理。
-- 修改已有数据库的字符集 ALTER DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 修改已有表的字符集和所有字段的字符集 ALTER TABLE test_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
3. 调整客户端连接字符集
客户端连接mysql时需要指定和数据库一致的字符集,不同连接方式设置方法不同:
命令行连接
在连接命令后添加--default-character-set=utf8mb4参数:
mysql -u root -p --default-character-set=utf8mb4 test_db
程序连接(以PHP为例)
在连接初始化时设置字符集:
<?php
$conn = new mysqli("localhost", "root", "password", "test_db");
// 设置连接字符集为utf8mb4
$conn->set_charset("utf8mb4");
?>
4. 修改mysql服务端默认配置
修改mysql配置文件my.cnf(linux)或my.ini(windows),在对应 section 下添加字符集配置,重启mysql服务生效:
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_general_ci init_connect = "SET NAMES utf8mb4"
5. 检查字段级别字符集
如果表和数据库字符集正确,但单个字段还是乱码,需要检查字段的字符集设置:
-- 查看表所有字段的字符集 SHOW FULL COLUMNS FROM test_table; -- 修改单个字段的字符集 ALTER TABLE test_table MODIFY COLUMN content VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
字符集选择建议
推荐使用utf8mb4作为全链路字符集,和utf8的区别如下:
| 字符集 | 支持字符范围 | 最大字节数 | 适用场景 |
|---|---|---|---|
| latin1 | 仅西欧字符 | 1字节 | 无中文场景 |
| utf8 | 基本多文种平面字符 | 3字节 | 无emoji和生僻字的中文场景 |
| utf8mb4 | 所有Unicode字符(含emoji、生僻字) | 4字节 | 全场景,尤其是有中文、emoji的场景 |
注意事项
修改已有数据的字符集时,如果之前数据已经用错误字符集存储,直接修改可能无法恢复数据,建议先备份数据,再尝试导出数据后重新导入到正确字符集的表中。
另外,排序规则utf8mb4_general_ci是大小写不敏感的通用排序规则,如果需要大小写敏感可以选择utf8mb4_bin。