B 树 、B+树学习记录

这里只讨论B树(不要念B减树)和B+树的概念,插入、查询、删除、实现起来有点困难,后续有时间再加内容吧。

学习参考来自:链接 博客

以下来自:链接

B树

前戏

我们大家都知道动态查找树能够提高查找效率,比如:二叉查找树,平衡二叉查找树,红黑树。他们查找效率的时间复杂度O(log2n),跟树的深度有关系,那么怎么样才能提高效率呢?当然最快捷的方式就是减少树的深度了。那么怎么减少树的深度呢?为了解答这个问题,我们慢慢来看,先看个实际问题吧。

问题背景

在大型的数据库存储中,实现索引查找,如果采用二叉查找树的查找的话,由于节点的存储数据是有限的(不可能将节点存储过多的数据,否则就变成线性的查找了),这样如果数据量很大的,就会导致树的深度过大从而造成磁盘IO操作过于频繁(你们知道磁盘IO操作是非常耗时的),就会导致效率非常低下。可能有童鞋会问了,那为什么不把节点索引加载到内存中,这样访问不就快了吗?其实这显然是不可能完成的,因为往往存储的索引可能就有好几个G了。全部加载到内存也是不现实的。能做的只有逐一加载每一个磁盘页,这里的磁盘页就相当于索引树的节点。

那怎么解决呢?就回到了前面的那个问题,可以减少树的深度。其中基本思想是:采用多叉树结构。也就是说,因为磁盘的操作费时费资源,如果过于频繁的多次查找势必效率低下。那么如何提高效率,即如何避免磁盘过于频繁的多次查找呢?根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,那么是不是便能有效减少磁盘查找存取的次数呢?那这种有效的树结构是一种怎样的树呢?

根据平衡二叉树的启发,自然就想到了平衡多路查找树结构。也就是本文的主题B-tree,好了废话不多说了,进入正题!

B-tree的简介

B-树就是我们平常说的B树,不要读成B减树了,它在文件系统中很有用(原因之前已经介绍了),我们先来看下一个m阶的Bs树具有如下几个特性:

  1. 根节点至少有两个子女
  2. 每个中间节点都包含k-1个元素和k个孩子,其中m/2<=k<=m
  3. 每个叶子节点都包含k-1元素,其中m/2<=k<=m
  4. 所有的叶子节点都位于同一层
  5. 每个节点的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。

简介有点复杂,我尝试用自己的语言解释解释。

1、好理解

2、中间的节点 如果有k个孩子节点,那么必须有k-1个元素,这样才能够准确的根据大小找到孩子节点

3、每个叶子节点元素的数量在[m/2-1,m-1]的区间内

4、好理解

5、每个节点的  k-1个元素 从小到大的排序  k个区间 分别对应孩子节点的数值区间大小

B+树

以下内容来自: 博客

么是B+树呢?在说B+树之前我们先了解一下为什么要有B树,其实这些树最开始都是为了解决某种系统中,查询效率低的问题。B树其实最开始源于的是二叉树,二叉树是只有左右孩子的树,当数据量越大的时候,二叉树的节点越多,那么当从根节点搜索的时候,影响查询效率。所以如果这些节点存储在外存储器中的话,每访问一个节点,相当于进行了一次I/O操作。

这里面说下外存储器和内存储器:

   外存储器:就是将数据存储到磁盘中,每次查找的某个元素的时候都要取磁盘中查找,然后再写入内存中,容量大,但是查询效率低。

   内存储器:就是将数据放在内存中,查询快,但是容量小。

我们大致了解了B树和什么是外存储器,内存储器,那么就知道其实B+树就是为了解决数据量大的时候存储在外存储器时候,查找效率低的问题。接下来就说下B+树的特点:

  1. 中间元素不存数据,只是当索引用,所有数据都保存在叶子结点中。

  2. 所有的中间节点在子节点中要么是最大的元素要么是最小的元素 。

  3. 叶子结点包含所有的数据,和指向这些元素的指针,而且叶子结点的元素形成了自小向大这样子的链表。

如下这个图就很好的说明了B+的特点

      看图其实可以看到一个节点可以存放多个数据,查找一个节点的时候可以有多个元素,大大提升查找效率,这就是为什么数据库索引用的就是B+树,因为索引很大,不可能都放在内存中,所以通常是以索引文件的形式放在磁盘上,所以当查找数据的时候就会有磁盘I/O的消耗,而B+树正可以解决这种问题,减少与磁盘的交互,因为进行一次I/O操作可以得到很多数据,增大查找数据的命中率。

这就可以很明显的看出B+树的优势:

  1. 单个节点可以存储更多的数据,减少I/O的次数。

  2. 查找性能更稳定,因为都是要查找到叶子结点。

  3. 叶子结点形成了有序链表,便于查询。

B+树是怎么进行查找的呢,分为单元素查找和范围查找

   单元素查找是从根一直查找到叶子结点,即使中间结点有这个元素也要查到叶子结点,因为中间结点只是索引,不存数据。比如要查元素3,如图:

  范围查找是直接从链表查,比如要查元素3到元素8的,如图:

B+树与B树的区别

  • 有k个子结点的结点必然有k个关键码;

  • 非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。

  • 树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。

用自己语言进行解释:

1、若一个节点有k个儿子节点,当它自己必须得有k个关键字(索引)

2、信息都存在叶子节点,其他节点只保留索引,方便查找

3、叶子节点从左至右形成一个有序得链表,可以遍历

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/106864709