《Mysql是怎样运行的》读书笔记三
字符集和比较规则
将字符映射成二进制的过程叫做编码,将二进制映射成字符的过程叫做解码。
我们看一下常用字符集的情况:ASCII字符集:
共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。ISO 8859-1字符集:
共收录256个字符,它在ASCII字符集
的基础上有扩充了128个西欧常用字符。GB2312字符集:
收录了汉字以及拉丁字母、希腊字母、日文平假名以及片假名字母、俄语西里尔字母,收录汉字6763个。GBK字符集
:GBK字符集
在GB2312字符集进行了扩充。UTF-8字符集:
几乎收录了当今世界各个国家/地区使用的字符,而且还在不断扩充。
umf8mb3:"阉割"过的UTF-8字符集,使用1~3字节表示字符。 umf8mb4:正宗的UTF-8字符集,使用1~4字节表示字符。
utf8是使用umf8mb3的别名。
比较规则是对某个字符集中字符比较大小的一种规则,一种字符集对应若干种比较规则,其中有一个默认比较规则,一个比较规则必须对应一个字符集。MySQL
有4个字符集和比较规则,分别是服务器级别、数据库级别、表级别、列级别。
服务器级别
(1)查看服务器级别的字符集
mysql> show variables like 'character_set_server';
(2)查看服务器级别的比较规则
mysql> show variables like 'collation_server';
数据库级别
(1)查看数据库级别的字符集
mysql> show variables like 'character_set_database';
(2)查看数据库级别的比较规则
mysql> show variables like 'collation_database';
表级别
我们可以在创建表和修改表的时候指定表的字符集和比较规则。如果表中没有指定,则使用表所在的数据库和字符集的比较规则作为该表的字符集和比较规则。
列级别
我们可以在创建列和修改列的时候指定列的字符集和比较规则。如果在创建列的没有显式指定字符集和比较规则,则该列默认使用表的字符集和比较规则。
客户端与服务器通信过程的使用的字符集
从本质上说,服务器接收到的请求就是一个字节序列,服务器将这个字节序列看作是使用系统变量character_set_client
代表的字符集进行编码的字节序列。(每个客户端与服务器建立连接之后,服务器都会为该客户端维护一个单独的character_set_client
变量,是SESSION级别的)
服务器会将请求的字节序列当做采用character_set_client
对应的字符集进行编码的字节序列,在真正处理请求时转换为使用SESSION级别的系统变量character_set_connection
对应的字符集进行编码的字节序列。
在客户端接收的值与表中的某列值比较时,列的字符集和排序规则的优先级更高。例如,
select * from t where c='我';
“我”采用的gbk
编码,列c
采用的utf8
字符集编码,这里需要将请求中的“我”先从gbk
字符集转换为utf8
。
以上面为例,在服务器生成响应的时候,服务器会将字符串“我”从utf8字符集编码转换character_set_result
系统变量对应的字符集编码后的字节序列,之后再发送给客户端。
系统变量 | 描述 |
---|---|
character_set_client | 服务器认为请求是按照该系统变量指定的字符集进行编码 |
character_set_connection | 服务器在处理请求时,会把请求字节序列从 character_set_client转换为character_set_connection |
character_set_result | 服务器采用该系统变量指定的字符集对返回客户端的字符串进行编码 |
在连接到服务器时,客户端将默认的字符集与用户名、密码等信息一起发送给服务器,服务器在接收后将character_set_client、character_set_connection
和character_set_result
这三个系统变量的值初始化为客户端的默认字符集。