我们相信:世界是美好的,你是我也是。 来玩一下解压小游戏吧!

苏南大叔在本文中的实验对象是:通过docker安装的mysql:5.7。探讨的是个古老的问题:“中文乱码”,解决方案就是设置字符集character属性为utf8mb4。具体来说,存在的解决方案很多,具体问题具体分析。

苏南大叔:mysql中文乱码,调试设置字符集charset的几种解决方案 - mysql字符集charset
mysql中文乱码,调试设置字符集charset的几种解决方案(图6-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10docker@28.0.4mysql@5.7heidisql@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,中文乱码或报错。如下图所示:

苏南大叔:mysql中文乱码,调试设置字符集charset的几种解决方案 - 中文字符不识别
mysql中文乱码,调试设置字符集charset的几种解决方案(图6-2)

验证字符集设置

无论通过哪种方式设置字符集,都可以通过以下命令验证:

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

确保 character_set_servercollation_server 的值为 utf8mb4utf8mb4_general_ci

苏南大叔:mysql中文乱码,调试设置字符集charset的几种解决方案 - mysql字符集验证01
mysql中文乱码,调试设置字符集charset的几种解决方案(图6-3)

苏南大叔:mysql中文乱码,调试设置字符集charset的几种解决方案 - mysql字符集验证02
mysql中文乱码,调试设置字符集charset的几种解决方案(图6-4)

对于默认字符集的是什么,可以通过下面的语句查看具体的建表语句。

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

苏南大叔:mysql中文乱码,调试设置字符集charset的几种解决方案 - 字符集检测结果
mysql中文乱码,调试设置字符集charset的几种解决方案(图6-5)

还可以具体查询某个字段的字符集,例如:

SELECT 
    COLUMN_NAME,
    CHARACTER_SET_NAME,
    COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE 
    TABLE_SCHEMA = 'sunan_db'
    AND TABLE_NAME = 'user';

苏南大叔:mysql中文乱码,调试设置字符集charset的几种解决方案 - 查询字段的字符集设置
mysql中文乱码,调试设置字符集charset的几种解决方案(图6-6)

解决方案一:建表时增加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经验文字,请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   mysql