MySql中文乱码问题本质是字符编码不匹配导致的,当数据存储、传输、读取环节的字符集不一致时,就会出现中文显示为问号、乱码符号的情况。不同场景下的乱码原因不同,对应的解决方式也有区别。

常见乱码场景及原因
首先我们需要明确几个核心字符集概念,MySql中涉及字符集的层级包括服务器级、数据库级、表级、字段级,还有客户端连接字符集。常见的乱码原因主要有以下几类:
- 数据库、表、字段的字符集没有设置为支持中文的编码,比如使用了默认的
latin1编码 - 客户端连接MySql时指定的字符集和数据库字符集不一致
- 数据导入导出时使用的字符集和数据库字符集不匹配
- 应用程序和数据库交互时没有正确设置字符集参数
已存在乱码的解决办法
1. 修改数据库字符集
如果当前数据库的字符集不支持中文,需要先修改数据库的默认字符集,执行以下SQL语句:
-- 修改数据库字符集为utf8mb4,排序规则为utf8mb4_general_ci ALTER DATABASE 数据库名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
2. 修改表的字符集
修改完数据库字符集后,还需要修改已有表的字符集,避免表和数据库字符集不一致:
-- 修改表字符集,同时转换表中所有字段的字符集 ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
3. 修改字段字符集
如果部分字段单独设置了字符集,还需要单独修改对应字段的字符集:
-- 修改指定字段的字符集 ALTER TABLE 表名 MODIFY 字段名 字段类型 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
4. 调整客户端连接字符集
即使数据库和表的字符集正确,如果客户端连接时没有指定正确的字符集,还是会出现乱码。可以在连接MySql后执行以下语句设置连接字符集:
-- 设置客户端连接字符集为utf8mb4 SET NAMES utf8mb4;
如果是通过应用程序连接MySql,需要在连接参数中指定字符集,比如Java连接MySql时可以在连接URL中添加参数:
// Java连接MySql时指定字符集参数 String url = "jdbc:mysql://127.0.0.1:3306/数据库名?useUnicode=true&characterEncoding=utf8mb4";
新建环境避免乱码的配置
如果是新建数据库和表,建议在创建时就指定正确的字符集,避免后续出现乱码问题:
1. 创建数据库时指定字符集
-- 创建数据库时直接指定字符集和排序规则 CREATE DATABASE IF NOT EXISTS 数据库名 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
2. 创建表时指定字符集
-- 创建表时指定表的字符集
CREATE TABLE 表名 (
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(255) NOT NULL
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
3. 修改MySql配置文件
可以修改MySql的配置文件my.cnf(Linux系统)或者my.ini(Windows系统),设置全局默认字符集,避免每次创建数据库和表都需要手动指定:
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_general_ci
修改完配置文件后需要重启MySql服务才能生效。
数据导入导出乱码解决
如果是通过mysqldump导出数据或者导入数据时出现乱码,可以在命令中指定字符集参数:
# 导出数据时指定字符集 mysqldump -u用户名 -p --default-character-set=utf8mb4 数据库名 > 导出文件.sql # 导入数据时指定字符集 mysql -u用户名 -p --default-character-set=utf8mb4 数据库名 < 导入文件.sql
注意事项
为什么推荐使用utf8mb4而不是utf8?因为MySql中的utf8其实是阉割版的utf8,只支持最多3个字节的字符,无法存储emoji表情和部分生僻中文,而utf8mb4是完整的utf8编码,支持4个字节的字符,兼容性更好。另外在修改字符集后,如果之前的乱码数据已经存储为错误的编码,修改字符集后可能无法直接恢复,这种情况需要重新插入正确的中文数据。