MySQL之字符集和比较规则

221 阅读4分钟

字符集

计算机只能存储二进制的0跟1,那么计算机是如何识别我们人类语言的呢?

  1. 建立字符跟二进制的映射关系(编码规则)

    如 'a'=> 0001 'b'=>0010 'c'=>0011 等

    将一个字符映射成一个二进制数据的过程叫做编码,将一个二进制数据映射到一个字符的过程叫做解码

  2. 界定一个范围(要把哪些字符映射为二进制)

    现实世界里有不同的语言,不同的语言里又包含不同的字符,如英文中字符包含A-Z,0-9,以及一些特殊符号,中文包含汉字,字母,数字,标点符号等,那么不同的语言就要设置不同的边界范围。

有了编码规则 + 界定范围, 我们也可以自定义我们自己的字符集,如小杨字符集(只包含a,b,c三个字符),小郭字符集(只包含a-z,0-9字符)等

为什么会出现乱码?

明白了字符集的由来,那么乱码的原因也就知道了: 编码和解码时用了不同或者不兼容的字符集。

比较规则

二进制的比较规则比较简单,那么字符又是如何比较大小的呢?

a跟b如何比较?

一个思路就是转化成二进制,比较二进制的大小

a跟A如何比较?

在建立映射时,为小写跟大写建立不同的映射关系 如何 a=>0001 A=> 0010,这样就可以比较大小了

有时,不区分大小写,比较字符,那么又该如何比较呢?

  1. 将两个大小写不同的字符全都转为大写或者小写。
  2. 比较这两个字符对应的二进制数据。

常见字符集

  • ASCII字符集  1字节 定长编码

  • GB2312 如果在ASCII字符中,占用1个字节,要不占用两个字节 变长编码

  • utf8 1-4字节   Unicode字符集:uft8,utf16,utf32 变长编码

注意:

  1. 我们怎么区分某个字节代表一个单独的字符还是代表某个字符的一部分呢?别忘了ASCII字符集只收录128个字符,使用0~127就可以表示全部字符,所以如果某个字节是在0~127之内的,就意味着一个字节代表一个单独的字符,否则就是两个字节代表一个单独的字符。

  2. 其实准确的说,utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、utf16、utf32这几种编码方案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个字符,utf32使用4个字节编码一个字符。MySQL中并不区分字符集和编码方案的概念,所以后边唠叨的时候把utf8、utf16、utf32都当作一种字符集对待。

MySQL中支持的字符集和比较规则

MySQL中的utf8跟utf8mb4

utf8字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而在MySQL中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以MySQL中定义了两个概念:

  • utf8mb3:使用1~3个字节表示字符。
  • utf8mb4:使用1~4个字节表示字符。

MySQLutf8utf8mb3的别名,如果大家有使用4字节编码一个字符的情况,比如存储一些emoji表情啥的,那请使用utf8mb4

字符集的查看

SHOW (CHARACTER SET|CHARSET) [LIKE 匹配的模式];

比较规则的查看

SHOW COLLATION [LIKE 匹配的模式];

注意:

每个字符集都有默认的比较规则,如utf8mb4的默认字符集为utf8mb4_general_ci

ci结尾的字符集比较规则,不区分大小写

字符集转换

set names 字符集;

文章来源

以上文章来源于《MySQL是怎样运行的-从根上理解MySQL》 [juejin.cn/book/684473…]