三毛笔记

MySQL字符集和校对规则

纯文本在计算机底层会转换为二进制保存,将字符转换为二进制码的过程,称为编码,将二进制码转换为字符的过程,称为解码。

字符集

编码和解码时所采用的规则,称为字符集。常见字符集有:ASCII、GBK、Unicode等。编写程序时,如果发现程序代码出现乱码的情况,就要马上去检查字符集是否正确。

UTF-8编码方式(二进制)
0xxxxxxx(ASCII码)1个字节
110xxxxx 10xxxxxx2个字节
1110xxxx 10xxxxxx 10xxxxxx3个字节
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx4个字节

MySQL支持字符集

MySQL自己定义了两个概念:

在MySQL中utf8是utf8mb3的别名,这就意味着使用1~3个字节来表示一个字符,如果想使用4字节编码一个字符,比如存储一些emoji表情啥的,那请使用utf8mb4。

查看字符集:SHOW (CHARACTER SET|CHARSET) [LIKE 匹配的模式];

校对规则

查看命令:SHOW COLLATION [LIKE 匹配的模式];,一种字符集可能对应着若干种校对规则(排序规则)。

后缀英文释义描述
_aiaccent insensitive不区分重音
_asaccent sensitive区分重音
_cicase insensitive不区分大小写
_cscase sensitive区分大小写
_binbinary以二进制方式比较

每种字符集都有一种默认的比较规则,比方说utf8字符集默认的比较规则就是utf8_general_ci。由于字符集和比较规则是互相有联系的,如果只修改了字符集,比较规则也会跟着变化,如果只修改了比较规则,字符集也会跟着变化。

MySQL有4个级别的字符集和比较规则,分别是:

服务器级别

MySQL提供了两个系统变量来表示服务器级别的字符集和比较规则:

系统变量描述
character_set_server服务器级别的字符集
collation_server服务器级别的比较规则

数据库级别

在创建和修改数据库时可指定该数据库的字符集和比较规则,具体语法如下:

CREATE DATABASE 数据库名
    [[DEFAULT] CHARACTER SET 字符集名称]
    [[DEFAULT] COLLATE 比较规则名称];

ALTER DATABASE 数据库名
    [[DEFAULT] CHARACTER SET 字符集名称]
    [[DEFAULT] COLLATE 比较规则名称];

如果创建数据库时不指定字符集和比较规则,则使用服务器级别的字符集和比较规则作为数据库的字符集和比较规则。

查看当前数据库使用的字符集和比较规则,可以查看下面两个系统变量的值(只读),前提是使用USE语句选择当前默认数据库,如果没有默认数据库,则变量与相应服务器级系统变量具有相同的值:

系统变量描述
character_set_database当前数据库的字符集
collation_database当前数据库的比较规则

表级别

也可以在创建和修改表的时候指定表的字符集和比较规则,如果没有指明字符集和比较规则,将使用该表所在数据库的字符集和比较规则作为该表的字符集和比较规则。

列级别

对于存储字符串的列,同一个表中不同列也可以有不同的字符集和比较规则,如果没有指明字符集和比较规则,将使用该列所在表的字符集和比较规则作为该列的字符集和比较规则。

字符集转换

客户端从发送请求到返回结果这个过程中伴随着多次字符集的转换,在这个过程中会用到3个系统变量:

系统变量描述
character_set_client服务器解码请求时使用的字符集
character_set_connection服务器处理请求时会把请求字符串从character_set_client转为character_set_connection
character_set_results服务器向客户端返回数据时使用的字符集

通常把这三个系统变量设置成和客户端使用的字符集一致,这样减少了很多无谓的字符集转换。为了方便我们设置,MySQL提供了一条非常简便的语句:SET NAMES 字符集名;。

如果想在启动客户端时就把这三个系统变量的值设置成一样的,可指定一个叫default-character-set的启动选项,比如在配置文件里可以这么写:

[client]
default-character-set=utf8

它起到的效果和执行一遍SET NAMES utf8;是一样一样的,都会将那三个系统变量的值设置成utf8。

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »