MySQL中文显示乱码的核心原因是字符集不匹配,当数据写入、存储、读取环节的字符集不一致时,就会出现中文无法正常显示的问题。解决该问题需要从数据库整体配置、表结构设置、客户端连接三个层面统一字符集。

常见乱码原因分析
乱码通常由以下几种情况导致:
- 数据库、表、字段的字符集不是支持中文的utf8mb4或者utf8
- 客户端连接数据库时未指定正确的字符集,默认使用latin1等不支持中文的字符集
- 数据库服务端默认字符集配置错误,新建库表时自动继承错误字符集
- 应用程序写入数据时的编码和数据库字符集不一致
服务端基础字符集配置
首先需要确保MySQL服务端的默认字符集支持中文,推荐统一使用utf8mb4,它完整支持所有Unicode字符,包括emoji和部分生僻字,比utf8更全面。修改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 init_connect = 'SET NAMES utf8mb4'
修改完成后重启MySQL服务,使配置生效。可以通过以下SQL语句验证服务端字符集:
-- 查看服务端字符集配置 SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%';
正常情况下,返回结果中character_set_server、character_set_database、character_set_client、character_set_connection、character_set_results都应该是utf8mb4。
已有库表的字符集修改
如果已经存在乱码的库表,需要单独修改其字符集,避免新数据正常但旧数据依然乱码。修改数据库字符集:
-- 修改数据库字符集 ALTER DATABASE 数据库名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
修改表的字符集,同时转换已有字段的字符集:
-- 修改表的字符集和所有字段的字符集 ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
如果只需要修改单个字段的字符集,可以使用以下语句:
-- 修改单个字段字符集 ALTER TABLE 表名 MODIFY 字段名 VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
客户端连接字符集设置
即使服务端和库表字符集正确,如果客户端连接时未指定字符集,依然会出现乱码。不同客户端的设置方式不同:
命令行客户端
连接数据库时指定字符集,或者在连接后执行设置语句:
# 连接时指定字符集 mysql -u 用户名 -p --default-character-set=utf8mb4 数据库名 # 连接后设置字符集 SET NAMES utf8mb4;
应用程序连接配置
不同编程语言的连接字符串需要添加字符集参数,以下是常见语言的示例:
Java(JDBC连接)
// JDBC连接字符串添加字符集参数 String url = "jdbc:mysql://127.0.0.1:3306/数据库名?useUnicode=true&characterEncoding=utf8mb4";
Python(PyMySQL连接)
import pymysql
# 连接时指定字符集
conn = pymysql.connect(
host='127.0.0.1',
user='用户名',
password='密码',
database='数据库名',
charset='utf8mb4'
)
PHP(PDO连接)
<?php // PDO连接时设置字符集 $dsn = 'mysql:host=127.0.0.1;dbname=数据库名;charset=utf8mb4'; $conn = new PDO($dsn, '用户名', '密码'); ?>
乱码问题排查步骤
如果依然出现乱码,可以按照以下步骤逐步排查:
- 先执行
SHOW VARIABLES LIKE 'character_set%';确认服务端所有字符集变量是否为utf8mb4 - 查看对应表的字符集:
SHOW CREATE TABLE 表名;,确认表和字段字符集是否正确 - 检查客户端连接时的字符集设置,确保连接参数中指定了utf8mb4
- 如果是旧数据乱码,确认修改字符集后是否对旧数据做了转码处理,直接修改字符集不会自动修复已有的乱码数据
- 检查应用程序写入数据时的编码,确保写入的字符串是UTF-8编码
注意事项
utf8mb4是utf8的超集,MySQL中的utf8实际是utf8mb3,最多支持3字节字符,无法存储部分生僻字和emoji,因此建议优先使用utf8mb4。另外修改已有表的字符集时,如果表数据量很大,转换操作可能会锁表,建议在业务低峰期执行。