一、B树
1、B树的结构:
B树是一种多路搜索树。
-
定义任意非叶子结点最多只有M个儿子,且M>2。
-
根结点的儿子数为[2, M]。
-
除根结点以外的非叶子结点的儿子数为[M/2, M]。
-
每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)。
-
非叶子结点的关键字个数=指向儿子的指针个数-1。
-
非叶子结点的关键字:K[1], K[2], …, K[M-1],且K[i] <= K[i+1]。
-
非叶子结点的指针:P[1], P[2], …,P[M](其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树)。
-
所有叶子结点位于同一层。
下图是一个M=4阶的B树。
2、B树的搜索过程:
B树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的是叶子结点。
查找文件29的过程:在每个节点,利用二分查找,找到对应的子节点
-
根据根结点指针找到文件目录的根磁盘块1,将其中的信息导入内存。(磁盘IO操作1次)
-
此时内存中有两个文件名17,35和三个存储其他磁盘页面地址的数据。根据算法我们发现17<29<35,因此我们找到指针p2。
-
根据p2指针,我们定位到磁盘块3,并将其中的信息导入内存。(磁盘IO操作2次)
-
此时内存中有两个文件名26,30和三个存储其他磁盘页面地址的数据。根据算法我们发现26<29<30,因此我们找到指针p2。
-
根据p2指针,我们定位到磁盘块8,并将其中的信息导入内存。(磁盘IO操作3次)
-
此时内存中有两个文件名28,29。根据算法我们查找到文件29,并定位了该文件内存的磁盘地址。
3、B树的特性:
-
关键字分布在整颗树的所有节点。
-
任何一个关键字出现且只出现在一个结点中。
-
搜索有可能在非叶子结点结束。
-
其搜索性能等价于在关键字全集内做一次二分查找。
二、B+树
1、B+树的结构
一般在数据库系统或文件系统中使用的B+Tree结构都在经典B+Tree的基础上进行了优化,增加了顺序访问指针。
B+树是B树的一种变形树,总结起来,数据库索引的B+树与B树的差异在于:
-
非叶子结点的子树指针与关键字个数相同。
-
非叶子结点的子树指针P[i],指向关键字值属于[K[i],K[i+1])的子树(注意,区间是前闭后开)。
-
为所有叶子结点增加一个链指针。
-
所有关键字都在叶子结点出现。
B+树的特性:
-
所有关键字都出现在叶子结点的链表中,且链表中的关键字是有序的。
-
搜索只在叶子结点命中。
-
非叶子结点相当于是叶子结点的索引,叶子结点是存储关键字数据的数据层。
总结:
B+树是一种多路搜索树,多用作数据库底层的数据存储结构,用于快速查找对应关键字数据,是从B树的结构优化过来的,B+树的所有的关键字信息都存储在叶子节点上,非叶子节点只做索引使用。
三、mysql索引数据结构:
1、mySQL索引数据结构:
mysql索引的数据结构采用的是 B+Tree,MyISAM和InnoDB的索引均采用B+树数据结构。
数据按页来保存,只保存在叶子节点上,叶子节点上也按照顺序添加了指针。非叶节点不存数据,只存指针。
2、B Tree的特点:
- 所有键值分布在整个树中;(区别与B+树,B+树的值只分部在叶子节点上)
- 任何关键字出现且只出现在一个节点中;(区别与B+树)
- 搜索有可能在非叶子节点结束;(区别与B+树,因为值都在叶子节点上,只有搜到叶子节点才能拿到值)
- 在关键字全集内做一次查找,性能逼近二分查找算法。
3、B+树的结构特点:
- B+树索引并不能找到一个给定键值的具体行,它找到的只是被查找数据行所在的页,接着数据库会把页读入到内存,再在内存中进行查找,最后得到要查找的数据。数据的读取是精确到页的,因为页是计算机管理存储器的逻辑块,IO的磁盘读取,每次都读取数据的大小是一个页大小的整数倍。
- 假设B+Tree的高度为h,一次检索最多需要 h-1 次 I/O(根节点常驻内存),复杂度 O(h) = O(logmN),m 指的是一个节点存储的数据的个数。实际应用场景中,M 通常较大,常常超过 100,因此树的高度一般都比较小,通常不超过 3。
4、 b-tree 和 和 b+tree 的区别:
1) B-树的关键字、索引和记录是放在一起的,B+树的非叶子节点中只有关键字和指向下一个节点的索引,记录只放在叶子节点中。
2) 在 B-树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而 B+树中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。
5、B+树的元素插入和删除逻辑:
https://blog.csdn.net/sunshine_lyn/article/details/82747596
主键索引和辅助索引的区别:https://learnku.com/articles/26852
参考博客:https://www.jianshu.com/p/d90f6b028d0e
彻底搞懂MySQL的索引:
https://mp.weixin.qq.com/s/OMgyqqi-r44KI-TjYKP59g