从发送请求到返回结果这个过程中伴随着多次字符集的转换, 在这个过程中会用到 3 个系统变量:
| 系统变量 | 描述 |
|---|---|
| character_set_client | 服务器解码请求时使用的字符集 |
| character_set_connection | 服务器处理请求时会把请求字符串从 character_set_client 转为character_set_connection |
| character_set_results | 服务器向客户端返回数据时使用的字符集 |
- character_set_connection 其实是服务器内部使用的字符集, 不太重要, 但是该字符集一定要 “大”
查看:
mysql> SHOW VARIABLES LIKE 'character_set_client';+----------------------+-------+| Variable_name | Value |+----------------------+-------+| character_set_client | utf8 |+----------------------+-------+1 row in set (0.00 sec)mysql> SHOW VARIABLES LIKE 'character_set_connection';+--------------------------+-------+| Variable_name | Value |+--------------------------+-------+| character_set_connection | utf8 |+--------------------------+-------+1 row in set (0.01 sec)mysql> SHOW VARIABLES LIKE 'character_set_results';+-----------------------+-------+| Variable_name | Value |+-----------------------+-------+| character_set_results | utf8 |+-----------------------+-------+1 row in set (0.00 sec)
MySQL 提供了简便的方法将它们设置为统一的字符集:
SET NAMES 字符集名;
mysql> SET NAMES utf8;
Query OK, 0 rows affected (0.00 sec)
请求从发送到结果返回过程中字符集的变化:
- 客户端发送请求所使用的字符集
一般情况下客户端所使用的字符集和当前操作系统一致:
- 类Unix系统使用的是utf8
- Windows使用的是gbk
- 服务器接收到客户端发送来的请求其实是一串二进制的字节,它会认为这串字节采用的字符集是character_set_client,然后把这串字节转换为character_set_connection字符集编码的字符
因为表t的列col采用的是gbk字符集,与character_set_connection一致,所以直接到列中找字节值为0xCED2的记录,最后找到了一条记录。
- 如果某个列使用的字符集和character_set_connection代表的字符集不一致的话,还需要进行一次字符集转换。
上一步骤找到的记录中的col列其实是一个字节串0xCED2,col列是采用gbk进行编码的,所以首先会将这个字节串使用gbk进行解码,得到字符串’我’,然后再把这个字符串使用character_set_results代表的字符集,也就是utf8进行编码,得到了新的字节串:0xE68891,然后发送给客户端。
- 由于客户端是用的字符集是utf8,所以可以顺利的将0xE68891解释成字符我,从而显示到我们的显示器上,所以我们人类也读懂了返回的结果。

