mysql中文乱码,调试设置字符集charset的几种解决方案
发布于 作者:苏南大叔 来源:程序如此灵动~

苏南大叔在本文中的实验对象是:通过docker
安装的mysql:5.7
。探讨的是个古老的问题:“中文乱码”,解决方案就是设置字符集character
属性为utf8mb4
。具体来说,存在的解决方案很多,具体问题具体分析。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10
,docker@28.0.4
,mysql@5.7
,heidisql@12.10.0.7000
。
实验对象
这里是使用docker
安装的龙套对象最经典的mysql:5.7
。目前,最新版的mysql:latest
/mysql@9.3.0
无此问题。
if not exist d:/data/mysql/my.cnf echo. > d:/data/mysql/my.cnf
docker run -d ^
--name mysql-container ^
--restart always ^
-e MYSQL_ROOT_PASSWORD=root ^
-e MYSQL_DATABASE=sunan_db ^
-v d:/data/mysql/my.cnf:/etc/mysql/my.cnf ^
-v d:/data/mysql/conf:/etc/mysql/conf.d ^
-v d:/data/mysql/data:/var/lib/mysql ^
-v d:/data/mysql/log:/var/log/mysql ^
-p 3306:3306 ^
mysql:5.7
存在问题
存在的问题是:新建的数据库和表,默认的字符集是latin1
,中文乱码或报错。如下图所示:
验证字符集设置
无论通过哪种方式设置字符集,都可以通过以下命令验证:
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
确保 character_set_server
和 collation_server
的值为 utf8mb4
和 utf8mb4_general_ci
。
对于默认字符集的是什么,可以通过下面的语句查看具体的建表语句。
SHOW CREATE DATABASE sunan_db;
SHOW CREATE TABLE user;
查询结果:
CREATE DATABASE `sunan_db` /*!40100 DEFAULT CHARACTER SET latin1 */
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gender` enum('male','female') DEFAULT NULL COMMENT '性别',
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
还可以具体查询某个字段的字符集,例如:
SELECT
COLUMN_NAME,
CHARACTER_SET_NAME,
COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = 'sunan_db'
AND TABLE_NAME = 'user';
解决方案一:建表时增加charset
建表的时候,就添加字符集设置,这个是最稳妥的方案。比如:
DROP TABLE IF EXISTS user;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gender` enum('男','女') DEFAULT NULL
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;
这个方案,就是每次建表或建数据库的时候,都要注意设置字符集。可能不适合懒人。
解决方案二:修改mysql配置
实际上就是修改my.ini
或者my.conf
,具体配置文件的位置,就需要具体测定了。对于苏南大叔这个docker
容器来说,那就是修改文件:d:/data/mysql/conf/my.conf
。添加以下内容:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
然后重启容器,确保MySQL
加载了新的配置文件。然而,这里存在着配置文件不生效的问题。待后续文章讨论。简单的来说,解决方案就是:进入容器,然后执行下面的代码。修改配置文件权限。
chmod 644 /etc/mysql/my.cnf
解决方案三:针对docker容器
mysql
容器初始化的时候,有两个字符集的参数。设置之后,和my.conf
的方案,效果是一样的。参考命令:
docker run -d ^
--name mysql-container ^
--restart always ^
-e MYSQL_ROOT_PASSWORD=root ^
-e MYSQL_DATABASE=sunan_db ^
-v d:/data/mysql/conf/my.cnf:/etc/mysql/my.cnf ^
-v d:/data/mysql/data:/var/lib/mysql ^
-v d:/data/mysql/log:/var/log/mysql ^
-p 3306:3306 ^
mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
注意:这两个字符集参数的位置,和别的参数位置不一样。
在方案二和方案三中,都涉及了两个参数。控制作用范围是:
参数 | 作用 |
---|---|
--character-set-server | 字符集 |
--collation-server | 排序规则 |
方案四:在客户端连接时设置字符集
如果使用客户端工具(如命令行、Python 脚本等)连接 MySQL,确保在连接时指定字符集。
在命令行中:
mysql -uroot -p --default-character-set=utf8mb4
在 Python 中:
import pymysql
conn = pymysql.connect(
host="localhost",
user="root",
password="root",
database="sunan_db",
charset="utf8mb4"
)
方案五:在运行时设置字符集
如果 MySQL
已经启动,可以通过SQL
命令动态设置字符集:
-- 设置客户端、连接和结果集的字符集
SET NAMES utf8mb4;
-- 或分别设置
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
这个方案,在很多年前的代码中经常使用。
方案六:升级到mysql最新版
截至到发稿,mysql
最新版9.3.0
,没有字符集的问题。默认值都是utf8mb4
。
结语
- 推荐字符集:使用
utf8mb4
,以支持完整的 Unicode 字符集(包括表情符号)。 - 设置方式:可以通过 Docker 命令、配置文件、客户端连接参数或运行时 SQL 命令设置字符集。
- 验证设置:通过
SHOW VARIABLES
检查字符集配置是否正确。
更多苏南大叔的mysql
经验文字,请点击:


