• 字符集
      • 规定字符到字节的映射
      • 同一个字符,对于不同的字符集,可能得到不同的表示
      • UTF-8 准确来说属于 Unicode 字符集的一种编码方式,但是 MySQL 并不区分字符集和编码方式,所以这里不必太在意
      • UTF-8 字符集需要 1~4 个字节,但我们常用的字符使用 1~3 个字节就可以表示了
      • MySQL 中的 utf8mb3 是阉割过的 UTF-8 字符集,只使用 1~3 个字节表示字符
      • utf8mb6 是正宗的 UTF-8 字符集,使用 1~4 个字符
      • 字符集的查看
        • SHOW (CHARACTER SET | CHARSET) [LIKE 匹配的模式];
        • Default collation 表示该字符集默认的比较规则
        • Maxlen 是该字符集最多需要几个字符来表示一个字节
      • 比较规则的查看
        • SHOW COLLATION [LIKE 匹配的模式];
        • 比较规则的命名:以关联的字符集开头,接着是比较规则所应用的语言。比如:polish 表示波兰语,general 是一种通用的比较规则。后缀表示是否区分重音、大小写,例如:ci 表示不区分大小写。
    • 各级别的字符集和比较规则

      • 服务器级别
      • SHOW VARIABLES LIKE ‘character_set_server’;
      • SHOW VARIABLES LIKE ‘collation_server’;
      • 可以在运行过程中修改这两个值,或者修改配置文件

        1. [server]
        2. character_set_server=gb2312
        3. collation_server=gb2312_chinese_ci
      • 数据库级别

        • SHOW VARIABLES LIKE ‘character_set_database’;
        • SHOW VARIABLES LIKE ‘collation_database’;
        • 注意查看这两个值需要先使用 use 选中数据库,否则显示的值将和服务器级别一样
        • 这两个系统变量只能展示,不能修改
        • 创建数据库时如果没有指定,将使用服务器级别的字符集和比较规则
      • 表级别
        • 如果未指定,与数据库级别一样
      • 列级别
        • 如果未指定,与表级别一样
      • 无论那种级别
        • 只修改字符集,比较规则变为该字符集默认的比较规则
        • 只修改比较规则,字符集变为该比较规则对应的字符集
    • 客户端与服务端通信
      • 字符集转码的概念
        • 字节序列 —(按照某种字符集解码)—>字符—>(按照另种字符集编码)—>另一个字节序列
      • 客户端编码请求字符串
        • 客户端以 mysql 为例,它接收用户输入的字符串,然后将其编码成字节序列后发送给服务端。一般情况下,编码使用到的字符集与操作系统当前使用的字符集一致。操作系统使用的字符集:读取以下三个环境变量,优先级从高到低 LC_ALL、LC_CTYPE、LANG。如果三个都没有设置,则使用操作系统默认的字符集。
        • 这个过程看成是用户告诉客户端:我要做什么。然后客户端翻译成服务端可以理解的语言并发送过去。
      • 服务端接收请求
        • 服务端维护一个 SESSION 级别的系统变量:character_set_client,这个变量表示一种字符集。当收到客户端请求的时候,服务端用这种字符集去解码。
        • 一般来说,我们应该保证客户端发送请求时使用的编码规则和服务端接收请求时使用的编码规则是一样的。但是我们也可以设置成不一样的:SET character_set_client=latin1;
        • 如果修改后的字符集不支持发送时使用的字符集,就可能出现乱码,并且会发出警告。相反,如果修改后的字符集支持发送时使用的字符集,那么就不会乱码,也没有警告(例如:客户端是 utf8,设置该变量为 utf8mb4)。
        • image.png
        • image.png
      • 服务端处理请求
        • 服务端对字节序列编码之后,又将其转换为字节序列,这里使用的字符集也是保存在一个 SESSION 级别的系统变量中:character_set_connection。
        • 这个变量的意义是:当需要比较两个字符串的时候,服务端得知道这两个字符串使用的字符集是什么,以及比较规则是什么。你可能想说:刚才不是已经设置了一个字符集了吗,直接用不就行了吗?目前看来默认的 character_set_connection 的确是客户端使用的字符集一样,这么一想,就觉得这个变量相当于给使用者一个可配置的可选项。另外,还有一个用来表示这些字符串应该使用的比较规则的变量:collation_connection。
        • image.png
        • image.png
        • 当字符串和某一列比较的时候,如果两者字符集或者比较规则不一样时,列的字符集和比较规则的优先级更高。
      • 服务器生成响应
        • 这次轮到服务端给客户端发信息,在发送前需要翻译成客户端能理解的语言,此时用到的字符集保存在:character_set_result。