前言
mysql最常用的数据结构是B+树,我们要探究探究为什么要选用这种数据结构。
二叉树
什么是二叉树
- 本身是有序树;
- 树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2;
二叉树的时间复杂度是O(logN),如图:
但是在一些极端情况会退化成链表,时间复杂度是O(N),如图:
红黑树
什么是红黑树
- 每个节点或者是黑色,或者是红色。
- 根节点是黑色。
- 每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
- 如果一个节点是红色的,则它的子节点必须是黑色的。
- 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
红黑树又称自动平衡二叉树,时间复杂度一般为O(logN),他会规避二叉树出现的那种极端情况会进行自选调整,同样这是一个复杂且费时的过程。
B树
什么是B树
- 根节点至少有2个子节点
- 每个中间节点都包含k-1个元素和k个子节点,其中 m/2 <= k <= m
- 每个叶子节点都包含k-1个元素,其中 m/2 <= k <= m
- 中间节点的元素按照升序排列
- 所有的叶子结点都位于同一层
B树又称为多路平衡查找树,他很好的去降低了树的高度,时间复杂度为O(logN)。
B+树
相比较B树,B+树又做了如下约定:
- 有k个子节点的中间节点就有k个元素(B树中是k-1个元素),也就是子节点数量 = 元素数量。 每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
- 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。
- 非叶子节点只保存索引,不保存数据。(B树中两者都保存)
- 叶子结点包含了全部元素的信息,并且叶子结点按照元素大小组成有序列表。
B+树为什么这样设计
1)B+树的磁盘读写代价更低
B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了;
2)B+树查询效率更加稳定
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当;
3)B+树便于范围查询(最重要的原因,范围查找是数据库的常态
B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。