其中每一种字符集又对应着若干种比较规则,我们以utf8字符集为例(太多了,也只展示几个):
mysql> SHOW COLLATION WHERE Charset='utf8';+--------------------------+---------+-----+---------+----------+---------+| Collation| Charset | Id| Default | Compiled | Sortlen |+--------------------------+---------+-----+---------+----------+---------+| utf8_general_ci| utf8|33 | Yes| Yes|1 || utf8_bin| utf8|83 || Yes|1 || utf8_unicode_ci| utf8| 192 || Yes|8 || utf8_icelandic_ci| utf8| 193 || Yes|8 || utf8_latvian_ci| utf8| 194 || Yes|8 || utf8_romanian_ci| utf8| 195 || Yes|8 |+--------------------------+---------+-----+---------+----------+---------+27 rows in set (0.00 sec)其中 utf8_general_ci 是utf8字符集默认的比较规则,在这种比较规则下是不区分大小写的,不过 utf8_bin 这种比较规则就是区分大小写的 。
在我们将请求中的字节序列转换为 character_set_connection 对应的字符集编码的字节序列后,也要配套一个对应的比较规则,这个比较规则就由 collation_connection 系统变量来指定 。我们现在通过SET命令来修改一下和 collation_connection 的值分别设置为 utf8 和 utf8_general_ci,然后比较一下 'a' 和 'A' :
mysql> SET character_set_connection=utf8;Query OK, 0 rows affected (0.00 sec)mysql> SET collation_connection=utf8_general_ci;Query OK, 0 rows affected (0.00 sec)mysql> SELECT 'a' = 'A';+-----------+| 'a' = 'A' |+-----------+|1 |+-----------+1 row in set (0.00 sec)可以看到在这种情况下这两个字符串就是相等的 。
我们现在通过SET命令来修改一下和 collation_connection 的值分别设置为 utf8 和 utf8_bin,然后比较一下 'a' 和 'A' :
mysql> SET character_set_connection=utf8;Query OK, 0 rows affected (0.00 sec)mysql> SET collation_connection=utf8_bin;Query OK, 0 rows affected (0.00 sec)mysql> SELECT 'a' = 'A';+-----------+| 'a' = 'A' |+-----------+|0 |+-----------+1 row in set (0.00 sec)可以看到在这种情况下这两个字符串就是不相等的 。
当然,如果我们并不需要单独指定将请求中的字符串采用何种字符集以及比较规则的话,并不用太关心 character_set_connection 和 collation_connection 设置成啥,不过需要注意一点,就是 character_set_connection 对应的字符集必须包含请求中的字符 。
服务器处理请求完毕生成对该客户端的响应为了故事的顺利发展,我们先创建一个表:
CREATE TABLE t (c VARCHAR(100)) ENGINE=INNODB CHARSET=utf8;然后向这个表插入一条记录:
INSERT INTO t VALUE('我');现在这个表中的数据就如下所示:
mysql> SELECT * FROM t;+------+| c|+------+| 我|+------+1 row in set (0.00 sec)我们可以看到该表中的字段其实是使用 utf8 字符集编码的,所以底层存放格式是: 0xE68891,将它读出后需要发送到客户端,是不是直接将 0xE68891 发送到客户端呢?这可不一定,这个取决于 character_set_result 系统变量的值,该系统变量也是一个SESSION级别的变量 。服务器会将该响应转换为 character_set_result 系统变量对应的字符集编码后的字节序列发送给客户端 。每个客户端在登录服务器的时候都会将客户端的默认字符集通知给服务器,然后服务器设置该客户端专属的 character_set_result。
我们也可以使用SET命令来设置 character_set_result 的值 。不过也需要注意,character_set_result 对应的字符集应该包含响应中的字符 。
这里再强调一遍,character_set_client 、 character_set_connection 和 character_set_result 这三个系统变量是服务器的系统变量,每个客户端在与服务器建立连接后,服务器都会为这个连接维护这三个变量,如图所示(我们假设连接1的这三个变量均为 utf8,连接1的这三个变量均为 gbk,连接1的这三个变量均为 ascii,):

文章插图
一般情况下 character_set_client 、 character_set_connection 和 character_set_result 这三个系统变量应该和客户端的默认字符集相同,SET names 命令可以一次性修改这三个系统变量:
SET NAMES 'charset_name'该语句和下边三个语句等效:SET character_set_client = charset_name;SET character_set_results = charset_name;SET character_set_connection = charset_name;不过这里需要大家特别注意,SET names 语句并不会改变客户端的默认字符集!客户端接收到响应客户端收到的响应其实仍然是一个字节序列 。客户端是如何将这个字节序列写到黑框框中的呢,这又涉及到应用程序和操作系统之间的一次交互 。
推荐阅读
- Linux环境下MySQL安装
- 在MySQL官网下载安装数据库
- 非常重要的mysql数据库定时备份!
- mysql5.7 使用XtraBackup2.4 全量备份还原
- 染发剂中的3.0或4.0是什么意思?了解颜色代码,染啥颜色一目了然
- 西游记中的歇后语 白骨精给唐僧送饭的歇后语
- 请收好Netcat网络工具中的瑞士军刀,从此故障诊断不用愁!
- URI中的 “//” 有什么用?
- 末影龙能打败凋零吗?
- 观察中的发现作文示例5篇 观察中的发现作文
