mysql中的字符集和排序规则(简述)

😝

Posted by 华仔 on May 22, 2019

相信大家对mysql的字符集了解的应该也都不少,刚刚也看了几篇博客,所以来简单的总结一下吧!噶哈哈~

utf8和utf8mb4的区别差异及选择:

先说结论吧,utf8mb4包含utf8,所以一般建议使用utf8mb4!

mb4(most bytes 4)是专门用来兼容4字节的unicode,utf8mb4是utf8的超集,所以除了改编码外不需要有其它另外的转换。

mysql支持的utf8编码最大字符长度为3字节,如果遇到4字节的宽字符就会插入异常。3字节的utf-8最大能编码的unicode字符是0xffff,即unicode中的基本多文种平面(BMP)! Ps.Emoji表情是一种特殊的unicode编码,它就是不在基本多文种平面的unicode编码。

基本多文种平面,BMP(Basic Multilingual Plane),或称第零平面(Plane 0),是Unicode中的一个编码区段。编码从U+0000至U+FFFF。 Unicode 基本多文种平面的示意图。每个写着数字的格子代表256个码点。

简单的描述mysql中的utf8字符集的缺点:放不下不常用的汉字以及一些Emoji表情等不在BMP的unicode编码。

utf8mb4选择排序规则

ps. 区别就直接copy的了

utf8mb4_ unicode_ ci 与 utf8mb4_ general_ ci 如何选择

字符除了需要存储,还需要排序或比较大小,涉及到与编码字符集对应的 排序字符集(collation)。ut8mb4对应的排序字符集常用的有 utf8mb4_unicode_ci 、 utf8mb4_general_ci ,到底采用哪个在 stackoverflow 上有个讨论, What’s the difference between utf8_general_ci and utf8_unicode_ci

主要从排序准确性和性能两方面看:

准确性

utf8mb4_unicode_ci 是基于标准的Unicode来排序和比较,能够在各种语言之间精确排序 utf8mb4_general_ci 没有实现Unicode排序规则,在遇到某些特殊语言或字符是,排序结果可能不是所期望的。 但是在绝大多数情况下,这种特殊字符的顺序一定要那么精确吗。比如Unicode把 ? 、 ? 当成 ss 和 OE 来看;而general会把它们当成 s 、 e ,再如 àá??ā? 各自都与 A 相等。

性能

utf8mb4_general_ci 在比较和排序的时候更快 utf8mb4_unicode_ci 在特殊情况下,Unicode排序规则为了能够处理特殊字符的情况,实现了略微复杂的排序算法。 但是在绝大多数情况下,不会发生此类复杂比较。general理论上比Unicode可能快些,但相比现在的CPU来说,它远远不足以成为考虑性能的因素,索引涉及、SQL设计才是。 我个人推荐是 utf8mb4_unicode_ci ,将来 8.0 里也极有可能使用变为默认的规则。 这也从另一个角度告诉我们,不要可能产生乱码的字段作为主键或唯一索引。我遇到过一例,以 url 来作为唯一索引,但是它记录的有可能是乱码,导致后来想把它们修复就特别麻烦。

结论

结论就我来总结一下吧~哈哈哈 1. 如果更注重于比较和排序速度就选择utf8mb4_general_ci; 2. 如果更注重于准确性就选择utf8mb4_unicode_ci; 3. 如果需要区分大小写就选择utf8mb4_binps.二进制存储区分大小写;

区分大小写对比实验

首先来看一下表结构:只有四个字段,后面那个name分别是不同排序规则的varchar字段

表结构

具体的name字段排序规则:

字段排序规则

然后看一下表中的数据:

浏览表中数据

测试正式开始:通过小写的abc对三个不同排序规则的字段进行等值比较

查询sql语句

结果:

实验结论:可以发现只有排序值为utf8mb4_bin的字段大小写敏感

怎么从utf8转换为utf8mb4:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4;

End. 如果发现讲的某个点有误,可以评论或发邮件通知我,一起走向人生巅峰