前言
之所以把【比较规则】这个事请放在最前面,是因为所有的数据结构都会通过排序的方式来加快检索(哈希表除外),例如有序的数组使用二分查找可以达到O(logN)复杂度,二叉树经过有序处理变成二叉搜索树后,查找效率也提高到O(logN),可以说,但凡涉及到高效检索能力的数据结构,首先要做的事就是让数据有序。Mysql使用的B+树索引同样应用到了排序这个方法,不但把数据做排序,也对索引值进行了排序,才实现了高效查找。要实现排序的前提是定义比较规则,就是说明a、b两个值到底哪个比较大的规则。类似于JDK中要实现Comparable才能使用一些sort函数。在Mysql中,这个比较规则包含两个内容:字符集和比较规则。
字符集和字符编码
字符集,Charset。一个字符集是一个确定的字符集合,也就是说字符集本质就是字符的集合,字符包含各种确定的文字、符号、图形等。例如ASCII字符集到目前为止一共定义了128个字符,包括数字、英文字符、标点符号等。规模更大的Unicode字符集定义类世界各国语言中的所有字符。集合之间存在包含关系,例如Unicode字符集就包含了ASCII字符集。
字符编码,Encodding,则是字符集中的字符到二进制表示的映射规则。例如Unicode的一种常用编码方式:UTF-8。显然字符集和字符编码从定义上来说是相互独立的,也就说一个字符集可以使用多个字符编码规则,同一个字符编码也可以编解码多个字符集,前提是能满足完备、无二义性要求,即不能冲突。
Mysql中并没有区分字符集和字符编码,而是把两者统一看待并分配一个小写的名字来指定,例如:ascii、utf8。UTF-8使用1~ 4个字节来编码一个字符,绝大部分的字符使用3字节就足够表示,例如汉字,部分特殊字符例如Emoji表情需要4个字节表示,为了提高存储效率,Mysql中定义了utf8mb3(别名:utf8)字符集:也就是Unicode字符集中使用UTF-8编码方式在1~ 3字节范围内的字符。而1~ 4个字节的字符集则命名为:utf8mb4。显然在如今1T固态硬盘只需要2~3百块的存储成本时代下,直接使用utf8mb4是最省事的方案。
在Mysql中可以通过执行如下命令查看所有支持的字符集:
SHOW CHARSET;
比较规则
有了字符集(字符编码)后,所有的值都可以使用二进制表示,就能进入计算机进行存储、计算。比较规则就是确定哪个大、哪个小的,最简单的方案就是直接用二进制比较大小,但通常我们需要先确定字符集,再来讨论比较规则,而且一个字符集可能对应多个比较规则。因为不同字符集之间不能说毫无联系,但也不能强行攀关系。
通过如下命令查看比较规则:
SHOW COLLATION LIKE 'utf8\_%';
实践中常用的utf8_general_ci(通用比较规则),也是utf8和utf8mb4字符集默认比较规则。
比较规则设置
Mysql中所有涉及到数据比较大小或者排序的地方都会使用到比较规则,需要提前设置规则。服务器、数据库、表、列都可以设置字符集、比较规则,且遵循从粗到细、从大到小的细颗粒度设置顺序,也就说,服务器级别的设置A,表级别设置B,最后生效的是B,其他同理。
通常使用如下SQL 设置字符集、比较规则:
DEFAULT CHARACTER SET 字符集名称 COLLATE 比较规则名称
显然字符集和比较规则属于基础核心配置,一旦选定就几乎不再更改,实践中通常需要DBA同研发共同确定,互联网公司常用的实践是在服务器、库级别设置好默认字符集和比较规则,如无特殊要求,新建的表直接使用默认值即可,不要单独设置字符集和比较规则,以免出错。
什么地方会使用
mysql使用B+树来组织数据和索引,B+树本质也是一个搜索树,需要根据比较规则来比较数据大小,在构建索引时,mysql通过对主键应用比较规则来组织数据,在一些查询sql例如where column= 'value'或者column between a and b时根据比较规则来检索数据。
总结
这里简单介绍了下MySql中的基础机制:字符集和比较规则,这是构建数据和索引的基础,后续讨论B+树如何分配数据、如何分页、如何查找数据时,都依赖于提前设定的比较规则,而比较规则又依赖于设定的字符集。因此要先理解字符集和比较规则,打下基础。
——比较规则&spm=1001.2101.3001.5002&articleId=140188470&d=1&t=3&u=0599076b650b469b84793f53bed3be81)
1万+

被折叠的 条评论
为什么被折叠?



