B树是为实现高效的磁盘存取而设计的多叉平衡搜索树。这个概念在文件系统,数据库系统中非常重要。当然,有关于B树的产生,发展,结构等等方面的介绍已经非常详细,所以本文只是介绍有关于B树和B+树最核心的知识点,也算是我本人的学习笔记。至于详细的资料,因为毕竟有着太多,所以不再赘述。可以向大家推荐一篇博客:从B树、B+树、B*树谈到R 树,这篇文章中,作者对于B树系列数据结构的讲解非常详细,我的这篇博客,也是大量参考了人家的很多例子和描述。
B树
一、基本原理
首先,简单说一下B树产生的原因。B树是一种查找树,我们知道,这一类树(比如二叉查找树,红黑树等等)最初生成的目的都是为了解决某种系统中,查找效率低的问题。B树也是如此,它最初启发于二叉查找树,二叉查找树的特点是每个非叶节点都只有两个孩子节点。然而这种做法会导致当数据量非常大时,二叉查找树的深度过深,搜索算法自根节点向下搜索时,需要访问的节点也就变的相当多。如果这些节点存储在外存储器中,每访问一个节点,相当于就是进行了一次I/O操作,随着树高度的增加,频繁的I/O操作一定会降低查询的效率。
这里有一个基本的概念,就是说我们从外存储器中读取信息的步骤,简单来分,大致有两步:
- 找到存储这个数据所对应的磁盘页面,这个过程是机械化的过程,需要依靠磁臂的转动,找到对应磁道,所以耗时长。
- 读取数据进内存,并实施运算,这是电子化的过程,相当快。
综上,对于外存储器的信息读取最大的时间消耗在于寻找磁盘页面。那么一个基本的想法就是能不能减少这种读取的次数,在一个磁盘页面上,多存储一些索引信息。B树的基本逻辑就是这个思路,它要改二叉为多叉,每个节点存储更多的指针信息,以降低I/O操作数。
二、基本结构
1. B树的定义
有关于B树概念的定义,不同的资料在表述上有所差别。我在这里采用《算导》中的定义,用最小度 [ M a t h P r o c e s s i n g E r r o r ] t t [Math Processing Error]t t [MathProcessingError]tt⌈2m⌉棵子树);
- 根节点要么没有子树,要么至少有2棵子树;
- 所有的叶子节点包含了全部的关键字以及这些关键字指向文件的指针,并且:
- 所有叶子节点中的关键字按大小顺序排列
- 相邻的叶子节点顺序链接(相当于是构成了一个顺序链表)
- 所有叶子节点在同一层
- 所有分支节点的关键字都是对应子树中关键字的最大值
比如,下图就是一个非常典型的B+树的例子。
B+树和B树相比,主要的不同点在以下3项:
- 内部节点中,关键字的个数与其子树的个数相同,不像B树种,子树的个数总比关键字个数多1个
- 所有指向文件的关键字及其指针都在叶子节点中,不像B树,有的指向文件的关键字是在内部节点中。换句话说,B+树中,内部节点仅仅起到索引的作用,
- 在搜索过程中,如果查询和内部节点的关键字一致,那么搜索过程不停止,而是继续向下搜索这个分支。
根据B+树的结构,我们可以发现B+树相比于B树,在文件系统,数据库系统当中,更有优势,原因如下:
-
B+树的磁盘读写代价更低
B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说I/O读写次数也就降低了。 -
B+树的查询效率更加稳定
由于内部结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。 -
B+树更有利于对数据库的扫描
B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题,而B+树只需要遍历叶子节点就可以解决对全部关键字信息的扫描,所以对于数据库中频繁使用的range query,B+树有着更高的性能。
</div> <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-095d4a0b23.css" rel="stylesheet"> </div><div id="article_content" class="article_content clearfix"> <div class="article-copyright"> <span class="creativecommons"> <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"> </a> <span>版权声明:本文为博主原创文章,遵循<a href="http://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener"> CC 4.0 BY-SA </a>版权协议,转载请附上原文出处链接和本声明。 </span> <div class="article-source-link2222"> 本文链接:<a href="https://blog.csdn.net/guoziqing506/article/details/64122287">https://blog.csdn.net/guoziqing506/article/details/64122287</a> </div> </span> </div> <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-3019150162.css"> <div id="content_views" class="markdown_views prism-atom-one-dark"> <!-- flowchart 箭头图标 勿删 --> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <p>B树是为实现高效的磁盘存取而设计的多叉平衡搜索树。这个概念在文件系统,数据库系统中非常重要。当然,有关于B树的产生,发展,结构等等方面的介绍已经非常详细,所以本文只是介绍有关于B树和B+树最核心的知识点,也算是我本人的学习笔记。至于详细的资料,因为毕竟有着太多,所以不再赘述。可以向大家推荐一篇博客:<a href="http://blog.csdn.net/v_july_v/article/details/6530142" rel="nofollow" data-token="786ca3c24e8a3f3bdda3855e36bc8dbb">从B树、B+树、B*树谈到R 树</a>,这篇文章中,作者对于B树系列数据结构的讲解非常详细,我的这篇博客,也是大量参考了人家的很多例子和描述。</p>
B树
一、基本原理
首先,简单说一下B树产生的原因。B树是一种查找树,我们知道,这一类树(比如二叉查找树,红黑树等等)最初生成的目的都是为了解决某种系统中,查找效率低的问题。B树也是如此,它最初启发于二叉查找树,二叉查找树的特点是每个非叶节点都只有两个孩子节点。然而这种做法会导致当数据量非常大时,二叉查找树的深度过深,搜索算法自根节点向下搜索时,需要访问的节点也就变的相当多。如果这些节点存储在外存储器中,每访问一个节点,相当于就是进行了一次I/O操作,随着树高度的增加,频繁的I/O操作一定会降低查询的效率。
这里有一个基本的概念,就是说我们从外存储器中读取信息的步骤,简单来分,大致有两步:
- 找到存储这个数据所对应的磁盘页面,这个过程是机械化的过程,需要依靠磁臂的转动,找到对应磁道,所以耗时长。
- 读取数据进内存,并实施运算,这是电子化的过程,相当快。
综上,对于外存储器的信息读取最大的时间消耗在于寻找磁盘页面。那么一个基本的想法就是能不能减少这种读取的次数,在一个磁盘页面上,多存储一些索引信息。B树的基本逻辑就是这个思路,它要改二叉为多叉,每个节点存储更多的指针信息,以降低I/O操作数。
二、基本结构
1. B树的定义
有关于B树概念的定义,不同的资料在表述上有所差别。我在这里采用《算导》中的定义,用最小度 [ M a t h P r o c e s s i n g E r r o r ] t t [Math Processing Error]t t [MathProcessingError]ttu是内部节点,那么分以下3种情况讨论: