字符编码和mysql编码

234 阅读4分钟

ASCII码

  1. bit 是一个二进制位(0和1)
  2. 1字节(byte) = 8个bit 可以组合出256种状态,每个状态对应一种符号
  3. ASCII码一共规定了128个字符的编码(只用了后7位,第一位统一为0),例如空格space=32,A=65

0xxxxxxx:ascii码 01000001为A , 10进制为65

unicode编码

ascii编码只有128个字符,无法表达世界上所有文字符号,unicode就是一个可以表达所有符号的编码

  • Unicode只是一个符号集

unicode的问题:编导字符只要1个字节,表达一些不常见的符号可能有N个字节,如果规定1个字符用4个字节存储,数字和字母存储时前面的字节就会出现很多0,会对存储造成浪费.

因此出现了多种unicode的存储方式,因此出现了utf8等编码方式

unicode表示ascii字符:去掉开头的0

例如: A的ASCII码 65(01000001), 转换成unicode为1000001,16进制为0040 (一般表示为\u0041)

utf8编码

uft8是互联网上使用最广泛的unicode实现方式,此外还有uft16,uft32等. utf-8的最大特点是变长的,本身支持1-4个字节(有说法是1-6个字节,后因为4位够用 废除了),

少数是汉字每个占用3个字节比较常用,多数占用4个字节,还有一些表情包等。

汉字:

  • 占3个字节的:基本等同于GBK,含21000多个汉字
  • 占4个字节的:中日韩超大字符集里面的汉字,有5万多个

英文符号数字:

  • 占一个字节

编码规则

  1. 单字节符号,第一位为0,后面为unicode码,所以与ascii码相同
  2. n字节(n>1) ,前n位都设为1 , 第n+1位设为0 , 其他字节前两位设为10 ,剩下的为unicode码
Unicode符号范围(十六进制)UTF-8编码方式 (二进制)
0000 0000-0000 007F0xxxxxxx
0000 0080-0000 07FF110xxxxx 10xxxxxx
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

例如:对"严"进行utf8编码

  1. 已知"严"的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此"严"的UTF-8编码需要三个字节,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。
  2. 然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,"严"的UTF-8编码是"11100100 10111000 10100101",转换成十六进制就是E4B8A5。

mysql字符集相关

  1. 字符集 utf8mb4 和 utf8 比较

mb4即 most bytes 4 , MySQL中utf8是utf8mb3的别名 MySQL的utf8是utfmb3,只有三个字节,省空间但不能表达全部的UTF-8,所以推荐使用utf8mb4

  1. utf8mb4_bin

将字符串每个字符用二进制数据编译存储,区分大小写,而且可以存二进制的内容。

  1. utf8mb4_general_ci 和 utf8mb4_unicode_ci 排序规则

ci即case insensitive

utf8mb4_general_ci           P=p  Q=q  R=r=Ř=ř   S=s=ß=Ś=ś=Ş=ş=Š=š  sh  ss    sz
utf8mb4_unicode_ci           P=p  Q=q  R=r=Ř=ř   S=s=Ś=ś=Ş=ş=Š=š    sh  ss=ß  sz

utf8mb4_general_ci 没有实现Unicode排序规则,在遇到某些特殊语言或者字符集,排序结果可能不一致。但是,在绝大多数情况下,这些特殊字符的顺序并不需要那么精确。

utf8mb4_unicode_ci 是基于标准的Unicode来排序和比较,能够在各种语言之间精确排序,Unicode排序规则为了能够处理特殊字符的情况,实现了略微复杂的排序算法。

总结: general_ci 更快,unicode_ci 更准确。但相比现在的CPU来说,它远远不足以成为考虑性能的因素,索引涉及、SQL设计才是。使

char 和 varchar 等字符类型建立索引

mysql对超过 767个字节 的字段的建立索引不支持,可以设置.

innodb中默认最大可对767个字节建立索引,所以 使用utf8 的列最多可对255个字符建立索引 使用utf8mb4 的列最多可对191个字符建立索引