• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)

互联网 diligentman 6个月前 (12-23) 47次浏览

大家好,我是方圆,我终于更新文章了!


1. 写在前头

最近在读《MySQL是怎样运行的》,它真的是一本儿写得非常用心的书。

这篇博客儿参考书中P44-P52,这部分读一遍不容易读懂(我认为),所以我想把它写的更通俗更好理解。

在读之前,首先一定要明白,MySQL客户端与服务器进行通信时,发送的请求和返回的响应本质上都是字节序列,我们要说的这三个系统变量,规定三个字符集,用于字节序列的转换


2. 咱给你把这三个“兄弟”说道说道

上代码!

show variables like 'character_set%';

[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)
瞧!这仨出来了!

它们都有同样的姓氏:character_set_,各自名字呐,分别叫clientconnectionresults,它们在服务器系统变量上都是SESSION级别的(也就是说,对应每一个客户端连接)

[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)
每个客户端在连接服务器时,都会将默认的字符集信息与用户名、密码等信息一起发给服务器,服务器根据发过来的信息,一下就把这三个系统变量规定好了!

别光看,得记住!


这下好,记住了昂,那我们接着说!

大哥character_set_client,它是干啥的?服务器接收到客户端发送过来的字节序列,会认为它是按照这个字符集进行编码的

(那,会按照这个字符集进行请求处理吗?)

不会的不会的,这时候就要character_set_connection上场了,我们要进行一次字符集的编码转换,转换成二哥,也就是character_set_connection对应的字符集,这样服务器才对客户端发过来的字节序列进行处理。

书中如下写:
服务器会将请求的字节序列当作采用character_set_client对应的字符集进行编码的字节序列,不过在真正处理请求时,又会将其转换为使用SESSION级别的系统变量character_set_connection对应的字符集进行编码的字节序列。

那有同学说了,这是不是有点儿麻烦呀?我们为什么不直接用character_set_client字符集,直接处理呢?

问到点儿上了,我们接着看。上代码!

select 'a' = 'A';

[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)
我们从结果中可以看到,这两个字符是相等的(因为我们此时的character_set_connection是utf8,对应的比较规则是utf8_general_ci不区分大小写)

我们将其比较规则修改一下,再进行比较。

set collation_connection=utf8_bin;

[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)

这个时候我们再看,这两个字符便不相等了,我们修改的是character_set_connection的比较规则,发现它起作用了!


我们接着说下一种情况。

还是上代码!

mysql> create table temp(
    -> c varchar(10)
    -> )engine=InnoDB charset=gbk;

mysql> insert into temp (c) values('我');

我们创建了如下表,只有一行数据。
[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)
接下来,我们要执行一条语句(铺垫一下,此时我们的character_set_connection为utf8,比较规则collation_connection为utf8_bin,而对应的列,我们在建表时已经规定它的编码方式了,为gbk和gbk_chinses_ci)

select * from temp where c = '我';

我们上边儿刚说过,服务器在进行字节序列处理的时候,根据的是character_set_connection的字符集进行编码,也就是utf8,比较规则collation_connection为utf8_bin,而此时语句中的编码便与之对应

另一方面,表的列中的,采用的则是gbk编码和gbk_chinses_ci比较规则,那么这种情况下,该如何比较呢?

我们执行看看结果!

喔!
[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)
在这种情况下啊,列的字符集和排列规则的优先级更高,也就是说,还需要从character_set_connection规定的字符集转换到对应的列的字符集(utf8->gbk)


大哥二哥聊完了,该说说三弟(character_set_results)了吧!

服务器在生成响应的时候,会按照character_set_results的编码集进行编码发送给客户端,就这一句话。

(简单!简单!)


3. 总结

[精读]Mysql中,三个重要的小兄弟(character_set_client、character_set_connection、character_set_results)


说在最后

大家可以关注一下我的公众号“芳圆想当图灵”,文章会优先同步到公众号上,大家私信也方便。

最近读完了《我想做一个能在你的葬礼上描述你一生的人》,很不错的散文集,学习之余读一两篇真的很不错。

我们相爱一生,一生还是太短 —— 沈从文


喜欢 (0)