一些重要的字符集
不幸的是,这个世界太大了,不同的人制定出了好多种字符集
,它们表示的字符范围和用到的编码规则可能都不一样。我们看一下一些常用字符集的情况:
-
ASCII
字符集共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才128个字符,所以可以使用1个字节来进行编码,我们看一些字符的编码方式:
'L' -> 01001100(十六进制:0x4C,十进制:76) 'M' -> 01001101(十六进制:0x4D,十进制:77)
-
ISO 8859-1
字符集共收录256个字符,是在
ASCII
字符集的基础上又扩充了128个西欧常用字符(包括德法两国的字母),也可以使用1个字节来进行编码。这个字符集也有一个别名latin1
。 -
GB2312
字符集收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母。其中收录汉字6763个,其他文字符号682个。同时这种字符集又兼容
ASCII
字符集,所以在编码方式上显得有些奇怪:- 如果该字符在
ASCII
字符集中,则采用1字节编码。 - 否则采用2字节编码。
这种表示一个字符需要的字节数可能不同的编码方式称为
变长编码方式
。比方说字符串'爱u'
,其中'爱'
需要用2个字节进行编码,编码后的十六进制表示为0xB0AE
,'u'
需要用1个字节进行编码,编码后的十六进制表示为0x75
,所以拼合起来就是0xB0AE75
。小贴士: 我们怎么区分某个字节代表一个单独的字符还是代表某个字符的一部分呢?别忘了`ASCII`字符集只收录128个字符,使用0~127就可以表示全部字符,所以如果某个字节是在0~127之内的,就意味着一个字节代表一个单独的字符,否则就是两个字节代表一个单独的字符。
- 如果该字符在
-
GBK
字符集GBK
字符集只是在收录字符范围上对GB2312
字符集作了扩充,编码方式上兼容GB2312
。 -
utf8
字符集收录地球上能想到的所有字符,而且还在不断扩充。这种字符集兼容
ASCII
字符集,采用变长编码方式,编码一个字符需要使用1~4个字节,比方说这样:'L' -> 01001100(十六进制:0x4C) '啊' -> 111001011001010110001010(十六进制:0xE5958A)
小贴士: 其实准确的说,utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、utf16、utf32这几种编码方案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个字符,utf32使用4个字节编码一个字符。更详细的Unicode和其编码方案的知识不是本书的重点,大家上网查查哈~ MySQL中并不区分字符集和编码方案的概念,所以后边唠叨的时候把utf8、utf16、utf32都当作一种字符集对待。
对于同一个字符,不同字符集也可能有不同的编码方式。比如对于汉字'我'
来说,ASCII
字符集中根本没有收录这个字符,utf8
和gb2312
字符集对汉字我
的编码方式如下:
utf8编码:111001101000100010010001 (3个字节,十六进制表示是:0xE68891)
gb2312编码:1011000010101110 (2个字节,十六进制表示是:0xB0AE)
MySQL中支持的字符集和排序规则
MySQL中的utf8和utf8mb4
我们上边说utf8
字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而在MySQL
中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以设计MySQL
的大叔偷偷的定义了两个概念:
-
utf8mb3
:阉割过的utf8
字符集,只使用1~3个字节表示字符。 -
utf8mb4
:正宗的utf8
字符集,使用1~4个字节表示字符。
有一点需要大家十分的注意,在MySQL
中utf8
是utf8mb3
的别名,所以之后在MySQL
中提到utf8
就意味着使用1~3个字节来表示一个字符,如果大家有使用4字节编码一个字符的情况,比如存储一些emoji表情啥的,那请使用utf8mb4
。
比较规则
这些比较规则的命名还挺有规律的,具体规律如下:
-
比较规则名称以与其关联的字符集的名称开头。如上图的查询结果的比较规则名称都是以
utf8
开头的。 -
后边紧跟着该比较规则主要作用于哪种语言,比如
utf8_polish_ci
表示以波兰语的规则比较,utf8_spanish_ci
是以西班牙语的规则比较,utf8_general_ci
是一种通用的比较规则。 -
名称后缀意味着该比较规则是否区分语言中的重音、大小写啥的,具体可以用的值如下:
后缀 英文释义 描述 _ai
accent insensitive
不区分重音 _as
accent sensitive
区分重音 _ci
case insensitive
不区分大小写 _cs
case sensitive
区分大小写 _bin
binary
以二进制方式比较 比如
utf8_general_ci
这个比较规则是以ci
结尾的,说明不区分大小写。
每种字符集对应若干种比较规则,每种字符集都有一种默认的比较规则,SHOW COLLATION
的返回结果中的Default
列的值为YES
的就是该字符集的默认比较规则,比方说utf8
字符集默认的比较规则就是utf8_general_ci
。