Mysql客户端到服务端字符集的转换
Mysql客户端和服务端之间的通信请求本质上是一个字符串,当然这个字符串会通过某种字符集编码转换为二进制数据,那是不是客户端和服务端之间的通信就只有一个字符集编码呢?如下所示
服务端编码
显然并不是这样,在服务端处理请求的过程中就涉及到三个字符集的转换,这三个转换分别对应三个系统变量如下所示
-
**
character_set_client
**:服务器解码客户端请求的字符串所用字符集。 -
**
character_set_connection
**:服务器处理请求时会将character_set_client
字符集转为character_set_connection
字符集。 -
**
character_set_results
**:服务端向客户端返回时所用的字符集编码。
查看字符集如下所示
### 为了篇幅,直接使用模糊查询查看,字符集展示如下
mysql> show variables like '%character%';
+--------------------------+-----------------------------------------+
| Variable_name | Value |
+--------------------------+-----------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-5.7.26/share/charsets/ |
+--------------------------+-----------------------------------------+
8 rows in set (0.00 sec)
客户端编码
并且客户端如果发送请求就会将字符串按照操作系统的字符集编码为二进制数据,在客户端接收到服务端请求后也会根据操作系统的字符集将二进制数据解码为字符串,那么操作系统字符集怎么查看呢?
### 在/etc/locale.conf文件 centos8默认字符集配置如下
[root@test ~]# cat /etc/locale.conf
LANG=en_US.UTF-8
转换过程
转换过程涉及到几种字符集的转换,步骤如下
-
客户端采用系统字符集默认是UTF8将操作数据库语句进行编码,变为二进制数据,这里仅限于采用
mysql -uroot -pxxx
接入的客户端,不包括市面流行的图形化界面客户端如Navicat,DBeaver等。 -
服务端接收到客户端发送的二进制数据后,通过字符集
character_set_client
字符集解码,变为字符串。 -
将解码后的字符串又采用
character_set_connection
字符集编码,变为二进制数据用于操作数据库,如果数据库列的字符集和character_set_connection
字符集不同,那么需要进行字符集转换,最终得到结果数据。 -
在返回给客户端之前还需要将结果根据
character_set_results
进行编码。 -
客户端接收到返回二进制数据,同样需要根据系统字符集进行解码,最终显示在客户端。
将上述文件转换为流程图,如下所示
字符集修改
服务端相关字符集系统变量是三个,如果想修改为了保证不会乱码一般需要同步修改,显然这样做很麻烦,那么我们可以采用如下两种方式,这两种方法的效果都是一次性将涉及到服务端编码的三个系统变量统一更新。
set方式
采用组合命令set names 字符集名称
,命令演示如下
mysql> show variables like '%character%';
+--------------------------+-----------------------------------------+
| Variable_name | Value |
+--------------------------+-----------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-5.7.26/share/charsets/ |
+--------------------------+-----------------------------------------+
8 rows in set (0.00 sec)
mysql> set names gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%character%';
+--------------------------+-----------------------------------------+
| Variable_name | Value |
+--------------------------+-----------------------------------------+
| character_set_client | gbk |
| character_set_connection | gbk |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | gbk |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-5.7.26/share/charsets/ |
+--------------------------+-----------------------------------------+
8 rows in set (0.01 sec)
修改配置文件
可以在默认配置文件/etc/my.cnf
,添加客户端启动系统配置参数
[client]
default-character-set=gbk
重连客户端就能得修改后的字符集,效果和set类似。