赞
踩
大家都知道mysql的数据结构是用b+tree来实现的。为什么不用其他数据结构呢?比如说hash、二叉树、红黑树、b-tree。要了解mysql底层的数据结构实现,需要先了解一下各个数据结构的特点以及存储方式:
Hash
哈希表是键值对的集合,通过键(key)值即可快速的取出对应的值(value),因此hash表查询的速度很快。但是,哈希算法有hash冲突的问题,也就是说多个不同的key最后得到的index相同,虽然hash通过链表的方法解决了hash冲突,但是如果使用hash用来存储数据,mysql可能会将每一行数据都存储在hash表中,这样数据都会通过hash表来维护,如果数据库操作数据量特别庞大,添加数据的时候会增加hash冲突次数。这是原因之一。
还有一个原因是因为hash不支持顺序查找,假如我们要对表中的数据进行排序和范围搜索,hash实现起来会很麻烦。
二叉树
二叉树的每一个节点都只有两个子节点,当需要向其插入更多的数据的时候,就必须要增加树的高度,而增加树的高度会导致IO的次数变多,对于二叉树而言,它的查找操作的时间复杂度就是树的高度,树的高度越高查询性能会随着数据的增多越来越低。
二叉树节点中,右边的节点一定会大于左边的节点。如果是非正常的倾斜(比如id是自增的情况)的二叉树,查询一次数据就相当于与全表搜索。
红黑树
红黑树是一个二叉平衡树。平衡树在插入和删除的时候,会通过旋转操作将树的左右节点达到平衡。红黑树的特性导致从根节点到叶子节点的最长路径不会超过最短路径的2倍。在实际场景应用当中,MySQL表数据,一般情况下都是比较庞大、海量的。如果使用红黑树,树的高度会特别高,红黑树虽说查询效率很高。但是在海量数据的情况下,树的高度并不可控,而且红黑树也需要不断的调整平衡性,也需要消耗性能。如果我们要查询的数据,正好在树的叶子节点。那查询会非常慢。
b-tree
B树的叶子结点具有相同的深度。所有索引元素不重复,节点中的数据索引从左到右递增排列。
那么为什么不选择B-tree呢?
b+tree
B+Tree和B-Tree的差距在于B+Tree的分支节点只存储索引信息,把数据都放在叶子节点上(非叶子节点是冗余节点,取得是叶子节点在磁盘节点上某些部分的索引),而且叶子节点包含了书中所有的索引结构,从左到右有序的递增的,这样保证了相近的数据都能存在同一块数据块里。叶子节点的每一页都包含了上一页和下一页的内存地址的指针索引,因此B+树具备了天然排序功能,在排序和范围查找的时候更方便。
同时B+树的查询次数更稳定,每次查询次数都是相同的,都需要查询到叶子节点。比如:在mysql中B+Tree默认的磁盘页节点大小是16KB,假设索引(主键索引)是bigint类型的,那么他会占8个字节,加上叶子结点的磁盘文件地址6个字节,节点索引大小大概是14tb,那么每一个索引行(页)就可以存储1170个索引元素,加入第三行存的是叶子节点,因为节点中包含所有数据信息(假设是整行数据,大小算1kb《比如一个表有二十个字段,每个字段都是bigint占用8个字节,可以算出,一行数据应该不会超出1KB,这是一个预估值》),那么b+tree树只需要三行就可以存放1170×1170×16=21,902,400 个索引元素了。所以B+Tree只需要三次的磁盘io就可以找到需要查找的元素了。也就说千万级的数据(走索引的情况)查找只需要经过三级就可以快速的查找到需要的元素了。
b-tree和b+tree的区别
mysql的存储引擎
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。