mysql编码问题——charset=utf8你真的弄明白了吗?(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: mysql编码问题——charset=utf8你真的弄明白了吗?(二)

② 第二种方式

image.png

 假如说连接器(connection)的字符集是GBk,这个过程又该是怎么进行的呢,下面我们仍然进行文字说明。

 首先,在客户端输入的字符,使用的字符集是GBK。当经过连接器的时候,连接器发现客户端发送过来的字符的字符集,与自身字符集相同,因此顺利通过了连接器。

 接着,当字符通过连接器发送给mysql服务器进行存储的时候,发现mysql服务器的字符集是UTF8,与自身的字符集GBK并不一致。因此,连接器此时又会进行"字符集的自动转换",将该字符(以GBK进行编码)转换为以UTF8格式的编码,进行显示,转换完成以后,再次发送给mysql服务器,进行最终的存储。


 “当我们从mysql服务器查数据的时候,返回过程又是怎么进行的呢?”

 首先 ,mysql服务器会将结果以UTF8编码格式进行返回,通过连接器的时候,连接器发现mysql服务器的字符集,与自身的字符集并不一致,于是连接器会进行"字符集的自动转换",将返回的结果(以UTF8进行编码)转换为以GBK格式的编码,进行显示。接着连接器又将转换后的结果,准备发送给客户端,此时发现客户端的字符集,与自身的字符集一致。因此直接发送给客户端,成功在CMD窗口中显示。


5、上述两种图示法的实际操作演示

1)先了解如下几个代码

1)设置客户端的字符集
set character_set_client=gbk;
2)设置连接器的字符集
set character_set_connection=utf8;
3)设置返回结果的字符集
set character_set_results=gbk;


2)代码演示过程如下

mysql> desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| sid   | int(11)     | NO   | PRI | NULL    | auto_increment |
| sname | varchar(20) | NO   |     | NULL    |                |
| age   | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> select * from student;
+-----+-------+------+
| sid | sname | age  |
+-----+-------+------+
|   1 | 张三  |   23 |
|   2 | 李四  |   25 |
|   3 | 王五  |   43 |
|   4 | 赵六  |   34 |
+-----+-------+------+
4 rows in set (0.00 sec)
mysql> #要想不乱码,需要指定客户端的编码,让连接器不理解错误。
mysql> #这样就不会存入错误数据。
mysql> #往回取数据的时候,还要告诉连接器,如果你从服务器返回,你应该给我转成什么格式。
mysql> #因此,一共需要设置3个参数:
mysql> #1、客户端发送的编码;
mysql> #2、连接器使用的编码;
mysql> #3、返回数据的编码;
mysql> 
mysql> 
mysql> 
mysql> #当前的情况是:客户端是GBK,服务器最终存储的是UTF8。
mysql> #因此,你就要明确告诉服务器,我的客户端是GBK的。
mysql> #命令如下:
mysql> set character_set_client=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> #再告诉连接器,使用UTF8。
mysql> #命令如下:
mysql> set character_set_connection=utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> #再告诉,如果你返回值给我看的话,也请返回GBK。
mysql> #命令如下:
mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into student(sname,age) values ("编码不乱",22);
Query OK, 1 row affected (0.10 sec)
mysql> select * from student;
+-----+----------+------+
| sid | sname    | age  |
+-----+----------+------+
|   1 | 张三     |   23 |
|   2 | 李四     |   25 |
|   3 | 王五     |   43 |
|   4 | 赵六     |   34 |
|   6 | 编码不乱 |   22 |
+-----+----------+------+
5 rows in set (0.00 sec)
mysql> #我的客户端是GBK,但是我偏要骗对方,是UTF8。
mysql> set character_set_client=utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into student(sname,age) values ("编码乱不乱?",22);
ERROR 1366 (HY000): Incorrect string value: '\xB1\xE0\xC2\xEB\xC2\xD2...' for column 'sname' at row 1
mysql> #此时,"编码乱不乱?"对应的GBK的内码,转换成UTF8,压根就出错,不允许插入。
mysql> set character_set_client=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> #我偏要对方返回给我的数据是UTF8。
mysql> set character_set_results=utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from student;
+-----+--------------+------+
| sid | sname        | age  |
+-----+--------------+------+
|   1 | 寮犱笁       |   23 |
|   2 | 鏉庡洓       |   25 |
|   3 | 鐜嬩簲       |   43 |
|   4 | 璧靛叚       |   34 |
|   6 | 缂栫爜涓嶄贡 |   22 |
+-----+--------------+------+
5 rows in set (0.00 sec)
mysql> #此时,请问我再插入数据。
mysql> insert into student(sname,age) values ("编码乱不乱?",22);
Query OK, 1 row affected (0.09 sec)
mysql> select * from student;
+-----+--------------------+------+
| sid | sname              | age  |
+-----+--------------------+------+
|   1 | 寮犱笁             |   23 |
|   2 | 鏉庡洓             |   25 |
|   3 | 鐜嬩簲             |   43 |
|   4 | 璧靛叚             |   34 |
|   6 | 缂栫爜涓嶄贡       |   22 |
|   7 | 缂栫爜涔变笉涔憋紵 |   22 |
+-----+--------------------+------+
6 rows in set (0.00 sec)
mysql> #虽然插入返回的数据仍然是乱码,但是属于的是,编码和解码不一致导致的乱码,可以修复。
mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from student;
+-----+--------------+------+
| sid | sname        | age  |
+-----+--------------+------+
|   1 | 张三         |   23 |
|   2 | 李四         |   25 |
|   3 | 王五         |   43 |
|   4 | 赵六         |   34 |
|   6 | 编码不乱     |   22 |
|   7 | 编码乱不乱? |   22 |
+-----+--------------+------+
6 rows in set (0.00 sec)
mysql> #再看另外一种情况:
mysql> #声明客户端是GBK;
mysql> set character_set_client=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> #声明连接器是GBK;
mysql> set character_set_connection=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> #声明返回值是GBK;
mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> #如上操作,插入中文,会不会乱码?
mysql> insert into student(sname,age) values ("真不乱?",666);
Query OK, 1 row affected (0.07 sec)
mysql> select * from student;
+-----+--------------+------+
| sid | sname        | age  |
+-----+--------------+------+
|   1 | 张三         |   23 |
|   2 | 李四         |   25 |
|   3 | 王五         |   43 |
|   4 | 赵六         |   34 |
|   6 | 编码不乱     |   22 |
|   7 | 编码乱不乱? |   22 |
|   8 | 真不乱?     |  666 |
+-----+--------------+------+
7 rows in set (0.00 sec)
mysql> #现在,我偏偏声明连接器的字符集是latin1。
mysql> set character_set_connection=latin1;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into student(sname,age) values ("还不乱?",888);
Query OK, 1 row affected, 1 warning (0.32 sec)
mysql> select * from student;
+-----+--------------+------+
| sid | sname        | age  |
+-----+--------------+------+
|   1 | 张三         |   23 |
|   2 | 李四         |   25 |
|   3 | 王五         |   43 |
|   4 | 赵六         |   34 |
|   6 | 编码不乱     |   22 |
|   7 | 编码乱不乱? |   22 |
|   8 | 真不乱?     |  666 |
|   9 | ????         |  888 |
+-----+--------------+------+
8 rows in set (0.00 sec)
mysql> #这次乱码,是因为latin1容量小,gbkt容量大。这个转换就像大鱼过小鱼网一样,丢了块肉。
mysql> #也就是说,大容量转换为小容量时,会丢失字节。
mysql> #思考一下:这次乱码能否修复?
mysql> #不能。。。
mysql> #因此,记住这个原则:
mysql> #字符集,服务器>=连接器>=客户端。
mysql> #也即:进行字符集的转换的时候,必须是小容量转换为大容量(小鱼过大鱼网)d,才不会丢失字节。
mysql> #########################################
mysql> #再回头看:一个比较巧的地方。
mysql> #client、connection、server字符集设置的都是GBK,不会导致乱码。
mysql> #如果三者都是GBK,可以简写成如下形式:
mysql> #set names gbk;
mysql> #这一句话,其实表示了3句话的含义。
mysql> Terminal close -- exit!


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
存储 关系型数据库 MySQL
MySQL库的操作『增删改查 ‖ 编码问题 ‖ 备份与恢复』
MySQL库的操作『增删改查 ‖ 编码问题 ‖ 备份与恢复』
88 0
|
7月前
|
SQL 关系型数据库 MySQL
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
|
7月前
|
存储 关系型数据库 MySQL
Mysql中utf8和utf8mb4区别
Mysql中utf8和utf8mb4区别
105 0
|
1月前
|
SQL 关系型数据库 MySQL
|
6月前
|
存储 自然语言处理 关系型数据库
|
6月前
|
存储 自然语言处理 搜索推荐
mysql中utf8、utf8mb4和utf8mb4_unicode_ci、utf8mb4_general_ci
mysql中utf8、utf8mb4和utf8mb4_unicode_ci、utf8mb4_general_ci
199 0
|
7月前
|
存储 关系型数据库 MySQL
从零开始学Mysql - 字符集和编码(下)
从零开始学Mysql - 字符集和编码(下)
143 0
|
7月前
|
存储 SQL 关系型数据库
从零开始学Mysql - 字符集和编码(上)
从零开始学Mysql - 字符集和编码(上)
169 0
|
7月前
|
存储 关系型数据库 MySQL
为什么不建议在MySQL中使用 utf8?
MySQL 字符编码集中有两套 UTF-8 编码实现:utf8 和 utf8mb4。 如果使用 utf8 的话,存储 emoji 符号和一些比较复杂的汉字、繁体字就会出错。
|
7月前
|
关系型数据库 MySQL Linux
【Linux 下 MySQL5.7 中文编码设置】
【Linux 下 MySQL5.7 中文编码设置】