彻底解决MySQL中的乱码问题

字符集转换概述
我们有必要说明一下,字符 其实是面向人类的一个概念,计算机可并不关心字符是什么,它只关心这个字符对应的字节编码是什么 。对于一个字节序列,计算机怎么知道它是使用什么字符集编码的呢?计算机不知道,所以其实在计算机中表示一个字符串时,都需要附带上它对应的字符集是什么,就像这样(以C++语言为例):
class String {byte* content;CHARSET_INFO* charset;}比方说我们现在有一个以 utf8 字符集编码的汉字 '我',那么意味着计算机中不仅仅要存储 '我' 的utf8编码 0xE68891,还需要存储它是使用什么字符集编码的信息,就像这样:
{content: 0xE68891;charset: utf8;}计算机内部包含将一种字符集转换成另一种字符集的函数库,也就是某个字符在某种字符集下的编码可以很顺利的转换为另一种字符集的编码,我们将这个过程称之为 字符集转换。比方说我们可以将上述采用utf8字符集编码的字符'我',转换成gbk字符集编码的形式,就变成了这样:
{content: 0xCED2;charset: gbk;}小贴士:我们上边所说的'编码'可以当作动词,也可以当作名词来理解 。当作动词的话意味着将一个字符映射到一个字节序列的过程,当作名词的话意味着一个字符对应的字节序列 。大家根据上下文理解'编码'的含义 。
MySQL客户端和服务器是怎么通信的MySQL客户端发送给服务器的请求以及服务器发送给客户端的响应其实都是遵从一定格式的,我们把它们通信过程中事先规定好的数据格式称之为MySQL通信协议,这个协议是公开的,我们可以简单的使用wireshark等截包软件十分方便的分析这个通信协议 。在了解了这个通信协议之后,我们甚至可以动手制作自己的客户端软件 。市面上的MySQL客户端软件多种多样,我们并不想各个都分析一下,现在只选取在MySQL安装目录的 bin 目录下自带的 mysql 程序(此处的 mysql 程序指的是名字叫做 mysql 的一个可执行文件),如图所示:
我们在计算机的黑框框中执行该可执行文件,就相当于启动了一个客户端,就像这样:

彻底解决MySQL中的乱码问题

文章插图
 
小贴士:我们这里的'黑框框'指的是windows操作系统中的cmd.exe或者UNIX系统中的Shell 。
我们通常是按照下述步骤使用MySQL的:
  1. 启动客户端并连接到服务器
  2. 客户端发送请求 。
  3. 服务器接收到请求
  4. 服务器处理请求
  5. 服务器处理请求完毕生成对该客户端的响应
  6. 客户端接收到响应
下边我们就详细分析一下每个步骤中都影响到了哪些字符集 。
启动客户端并连接到服务器过程每个MySQL客户端都维护者一个客户端默认字符集,这个默认字符集按照下边的套路进行取值: