B树
B树是一种自平衡的多叉树。每个节点都存储关键字值。其左子节点的关键字值小于该节点关键字值,且右子节点的关键字值大于或等于该节点关键字值。B树每一个节点都包含key和value,查询效率比B+树高。
B+树
B+树也是一种自平衡的多叉树。其基本定义与B树相同,不同点在于数据只出现在叶子节点,所有叶子节点增加了一个链指针,方便进行范围查询。
B+树中间节点不存放数据,所以同样大小的磁盘页上可以容纳更多节点元素,访问叶子节点上关联的数据也具有更好的缓存命中率。并且数据顺序排列并且相连,所以便于区间查找和搜索。
AVL树
AVL树是一种改进版的搜索二叉树,其引入平衡因子(左子树高度与右子树高度之差的绝对值),通过旋转使其尽量保持平衡。
任何一个节点的左子树高度与右子树高度之差的绝对值不超过1.
红黑树
红黑树本身是由2-3树发展而来,红黑树是保持黑平衡的二叉树,其查找会比AVL树慢一点,添加和删除元素会比AVL树快一点。增删改查统计性能上讲,红黑树更优。
红黑树主要特征是在每个节点上增加一个属性表示节点颜色,可以红色或黑色。红黑树和AVL树类似,都是在进行插入和删除时通过旋转保持自身平衡,从而获得较高的查找性能。红黑树保证从根节点到叶尾的最长路径不超过最短路径的2倍,所以最差时间复杂度o(logn)。红黑树通过重新着色和左右旋转,更加高效地完成插入和删除之后的自平衡调整。
为什么数据库不用红黑树用B+树?
红黑树的出度为2,而B树的出度一般都非常大。红黑树的树高很明显比B树大非常多,IO次数很多,导致会比较慢,因此检索的次数也就更多。
B+树相比于B树更适合外存索引,拥有更大的出度,IO次数较少,检索效率会更高。
为什么说B+树比B树更适合实际应用中操作系统的文件索引和数据库索引?
B+树的磁盘读写代价更低,B+树的查询效率更加稳定,数据库索引采用B+树而不是B树的主要原因:B+树只要遍历叶子节点就可以实现整棵树的遍历,而且在数据库中基于范围的查询是非常频繁的,而B树只能中序遍历所有节点,效率太低。
B +树的特点:
- 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的
- 不可能在非叶子结点命中
- 非叶子节点相当于叶子节点的索引(稀疏索引),叶子节点相当于是存储(关键字)数据的数据层
增加B+树的路数可以降低树的高度,那么无限增加树的路数是不是可以有最优的查找效率?
不可以,因为这样会形成一个有序数组,文件系统和数据库的索引都是存在硬盘上的,并且如果数据量大的话,不一定能一次性加载到内存中。有序数组没法一次性加载进内存,这时候B+树的多路存储威力就出来了,可以每次加载B+树的一个节点,然后一步步往下找
为什么MySQL索引要使用B+树,而不是B树或者红黑树?
MySQL中的数据一般是放在磁盘中的,读取数据的时候肯定会有访问磁盘的操作,磁盘中有两个机械运动的部分,盘片旋转和磁臂移动。盘片旋转就是多少转每分钟,磁盘移动则是在盘片旋转到指定位置后,移动磁臂开始进行数据的读写。存在一个定位到磁盘中的块的过程,定位是磁盘存取中花费时间比较大的一块,机械运动花费时间远远大于电子运动的时间。当大规模数据存储到磁盘中的时候,定位是一个非常花费时间的过程,我们可以通过B树进行优化,提高读取时定位的效率。
构造一个多阶的B树,在尽量多的节点上存储相关的信息,保证层数(树的高度)尽量的少,以便更快地找到信息,减少磁盘I/O操作。B树是平衡树,每个结点到叶子节点的高度都是相同,保证每个查询的稳定。
为什么MySQL索引适用B+树而不是hash表和B树?
- 利用Hash需要把数据全部加载到内存中,如果数据量大,是一件消耗内存的事,而采用B+树,是基于按照节点分段加载,减少内存消耗
- 和业务场景有关,对于唯一查找(查找一个值),Hash确实更快,但数据库中经常查询多条数据,这时候由于B+数据的有序性,与叶子节点又是链表相连,他的查询效率会比Hash快的多
- B+树的非叶子节点不保存数据,只保存子树的临界值(最大或最小),所以同样大小的节点,B+树相对于B树能够有更多的分支,使得这棵树更加矮胖,查询时做的I/O操作次数也更少。
既然Hash比B+树更快,为什么MySQL用B+树来存储索引呢?
MySQL中存储索引用的数据结构是B+树,B+树的查询时间跟树的高度有关,是log(n),如果用Hash存储,查询时间是o(1)
采用Hash存储确实要更快,但是采用B+树来存储索引的原因主要有以下两点:
- 从内存角度看,数据库中的索引一般是在磁盘上,数据量大的时候可能无法一次性装入内存,B+树的设计可以允许数据分批加载
- 从业务场景看,如果只选择一个数据那确实是hash更快,但是数据库中经常会选中多条,由于B+树索引有序,并且又是链表相连,他的查询比Hash快很多
map、set是怎么实现的,红黑树是怎么能够同时实现这两种容器的?为什么使用红黑树?
- 它们的底层都是以红黑树的结构实现,因此插入删除等操作都是在o(logn)时间内完成,因此可以完成高效的插入删除
- 定义一个模板参数,如果他是key,那么他就是set;如果他是key-value,那么他就是map;底层是红黑树,实现map的红黑树的节点数据类型是key+value,实现set的节点数据类型是value
- 因为map和set要求是自动排序的,红黑树能够实现这一功能,而且时间复杂度比较低。
5947

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



