B树和B +树之间有什么区别?


293

b树中,您可以将密钥和数据存储在内部节点和叶节点中,但是在b +树中,您只需将数据存储在叶节点中

在b +树中执行上述操作是否有任何优势?

为什么不在各处都使用b树而不是b +树,因为从直观上看它们似乎快得多?

我的意思是,为什么您需要在b +树中复制密钥(数据)?


37
我认为他们所说的是“ B树”与B +树。它们的意思是连字符,而不是减号。
stu 2015年

Answers:


421

下图有助于显示B +树和B树之间的差异。

B +树的优点:

  • 因为B +树没有与内部节点关联的数据,所以更多的键可以容纳在内存页面上。因此,它将需要较少的高速缓存未命中,以便访问叶节点上的数据。
  • B +树的叶节点是链接的,因此对树中的所有对象进行全面扫描仅需要线性遍历所有叶节点。另一方面,AB树将需要遍历树中的每个级别。与B +叶子的线性遍历相比,这种全树遍历可能涉及更多的缓存未命中。

B树的优势:

  • 因为B树的每个键都包含数据,所以频繁访问的节点可以更靠近根,因此可以更快地访问。

B和B +树


2
它们对叶节点中的条目数有任何约束吗?
TLE 2014年

38
@TLE好问题!是。硬盘一次访问最少一个内存页,因此我们希望将所有指针放入单个内存页中。我们希望每个叶子访问只需要读取一个磁盘,所以我们不想分配超过一个叶子的指针页面大小。如果我们用指针的页面大小填充一个叶子,然后要向该叶子添加另一个指针,则我们将创建该节点的两个孩子,并将叶子的一半指针分配给每个新孩子。当然,可能需要进行一些改组以确保树的高度保持最小。这有帮助吗?
罗斯·佩隆

B树的每个叶节点的最后一个指针应指向下一个叶节点,对吗?
卡米诺2014年

8
很抱歉碰到这样一个老话题,但是@Babyburger关于camino的评论如何正确的评论实际上是不正确的。实际上,B树没有连接的叶节点。当然是B +。
杰森

感谢出色的回答,当在数据库上下文中的B / B +树中需要对对象进行全面扫描时,用例是什么?由于它主要用于索引,因此搜索几乎不需要对整个树进行扫描,而是通过索引路径进行遍历,对吗?
Siddhartha

113

与B树相比,B +树的主要优点是它们允许您通过删除指向数据的指针来打包更多指向其他节点的指针,从而增加扇出并可能减小树的深度。

缺点是,当您在内部节点中找到匹配项时,不会早日淘汰。但是,由于这两种数据结构都具有巨大的扇出状态,因此无论如何,绝大多数匹配项都将位于叶节点上,从而使B +树的平均效率更高。


1
我更喜欢杰夫的答案,因为它强调了进行完整扫描时效率的差异。
Rose Perrone

我真的很困惑,因为使用有序遍历遍历b树将在O(n)时间中按排序顺序读取所有值。如果每个树节点的大小都针对物理页面大小进行了优化,那么似乎事情就不会再变得最优了。相反,到达b +树中的第一个(最小)值的成本为O(log n),然后遍历每片叶子的成本为O(n),因此总成本为O(log n + n)。这是更多的工作,更多的磁盘读取是有意义的,因为树中包含所有这些额外的数据。我不明白
埃里克(Eric)

上述句子中的“扇出”又是什么意思?
Jorge Bucaran '16

3
@JorgeBucaran扇出=来自节点的边数
bantmen '16

33

B + Tree进行完整扫描要容易得多,并且性能更高,就像查看树索引的每条数据一样,因为终端节点形成了一个链表。要对B树进行完整扫描,您需要对树进行遍历以查找所有数据。

另一方面,当您执行查找(通过键查找特定的数据)时,尤其是当树位于RAM或其他非块存储中时,B树会更快。由于您可以在树中提升常用节点,因此获取数据所需的比较较少。


1
您是否同意,然后将B +树用于可能对所有数据进行顺序读取从而能够跨越各个叶子的情况。而B树对于随机访问情况是理想的?
JDPeckham '17

31
  1. 在B树中,搜索关键字和数据存储在内部或叶节点中。但是在B +树中,数据仅存储在叶节点中。
  2. 完全扫描B +树非常容易,因为所有数据都在叶节点中找到。完整扫描B树需要完整遍历。
  3. 在B树中,可以在叶节点或内部节点中找到数据。内部节点的删除非常复杂。在B +树中,仅在叶节点中找到数据。叶节点的删除很容易。
  4. B树中的插入比B +树复杂。
  5. B +树存储冗余搜索关键字,但B树没有冗余值。
  6. 在B +树中,叶节点数据按顺序链表进行排序,但在B树中,叶节点无法使用链表存储。许多数据库系统的实现都喜欢B +树的结构简单性。

15

数据库系统概念示例5

B +树 B +树

对应的B树 Btree


5
我认为B树没有链接到该节点的子节点的链接。例如从Clearview bucketMianus Bucket。无论如何,这样做并没有多大意义,因为Downtown bucket如果您想在B树中进行索引扫描(需要回溯),则在两者之间您将搜索到很多东西。你从哪儿得到的?
埃文·卡罗尔

1
@EvanCarroll数据库系统概念第五,也许您需要与作者确认:)
camino

11

定义“快得多”。渐近地,它们大致相同。不同之处在于它们如何利用辅助存储。B树B +树上的Wikipedia文章看起来非常值得信赖。


2
我同意查理。由于B树的一个节点代表一个辅助存储页面或块,因此从一个节点到另一个节点的传递需要耗时的页面更改。

11

Adegoke A,阿米特

我猜想人们所缺少的一个关键点是数据和指针之间的差异,如本节所述。

指针:指向其他节点的指针。

数据:-在数据库索引的上下文中,数据只是指向位于其他位置的真实数据(行)的另一个指针。

因此,在B树的情况下,每个节点具有三个信息密钥,即与该密钥相关联的数据的指针和对子节点的指针。

在B +树中,内部节点保留指向子节点的键和指针,而叶子节点保留指向关联数据的键和指针。对于给定的节点大小,这允许更多数量的密钥。节点的大小主要由块大小决定。

上面已经很好地解释了每个节点具有更多键的优点,因此我将省去打字工作。


10

B +树在基于块的存储(例如,硬盘)中特别有用。考虑到这一点,您将获得一些优势,例如(从我的头上来):

  • 高扇出度/低深度:这意味着您必须减少获取数据的块数。将数据与指针混合在一起,每次读取将获得更少的指针,因此您需要更多的探索才能获得数据

  • 简单一致的块存储:内部节点具有N个指针,没有其他内容,叶节点具有数据,没有其他内容。这样就可以轻松解析,调试甚至重构。

  • 高密钥密度意味着几乎可以肯定顶部节点在高速缓存中,在许多情况下,所有内部节点都得到快速高速缓存,因此仅数据访问必须转到磁盘。


2
主要用于内存树;但是还有其他一些流行的选项,例如红黑树,跳过列表等等。
哈维尔

B树还被设计用于有效的基于块的存储,从而限制了节点访问的渐近次数。否则,如果使用具有随机访问权限的类似内存的存储介质,则可以使用自平衡二叉树(例如红黑树)来获得更好的结果。
dionyziz 2012年

您的第一点不应该说“更少的寻找”而不是“更多的寻找”。深度较小->搜寻次数较少
杰西(Jesse)2012年

1
@Jesse:高扇出=>低深度=>更少的寻道,但是将数据和指针混合意味着更少的指针=>低扇出=>更多的深度=>更多的寻道
哈维尔2012年

1
@AdegokeA:B +树有两种类型的节点:内部节点只有键和指针,没有数据;和叶节点,有数据,没有指针。允许每个内部节点上的最大键数。如果将数据存储在内部节点上,则可以容纳更少的指针,并且树会更高。
哈维尔

5

在B +树中,由于只有指针存储在内部节点中,所以它们的大小变得明显小于B树的内部节点(后者同时存储数据和键)。因此,可以在单个磁盘读取中从外部存储中获取B +树的索引,并对其进行处理以找到目标的位置。如果它是B树,则每个决策过程都需要读取磁盘。希望我说清楚!:)


4

2

举一个例子-您有一个表,每行有大量数据。这意味着该对象的每个实例都是Big。

如果您在此处使用B树,则大部分时间都花在扫描带有数据的页面上-这没有用。在数据库中,这就是使用B +树避免扫描对象数据的原因。

B +树将键与数据分开。

但是,如果您的数据大小较小,则可以使用B树所做的密钥存储它们。


1
“如果您在这里使用B树,则大部分时间都花在扫描数据页面上” –不必要。B树节点只能将“指针”保留到磁盘上的数据,而不能保留数据本身。
TT_

2

B树和B +树之间的主要区别是B树消除了搜索键值的冗余存储。由于在B树中没有重复搜索键,因此我们可能无法使用更少的树节点来存储索引但是,由于非叶子节点中出现的搜索关键字在B树中没有出现,因此我们不得不为非叶子节点中的每个搜索关键字包括一个额外的指针字段。它们是B树的空间优势,因为不会发生重复并且可以用于大索引。


1
有趣的是,关于重复的想法在此处的回复中是唯一的,并且比b + tree的有序遍历比b-tree的有序遍历更有意义。据我所知,这不是很正确,或者不是整个故事,因为遍历b树的顺序是O(n)并在b + tree中找到最小的节点是O(log n),然后除此以外,遍历每片叶子的时间是O(n)。但是,如果要索引的值范围较小,例如布尔字段,则由于b + tree具有重复处理,因此它比b-tree有意义得多。
埃里克

1

B +树是一棵平衡树,其中从树的根到叶的每条路径都具有相同的长度,并且树的每个非叶节点都有[n / 2]和[n]个子节点,其中n是为特定的树固定。它包含索引页和数据页。二叉树的每个父节点只有两个孩子,B +树的每个父节点可以有可变数量的孩子


1
为了清楚起见,B树不是二叉树。实际上,B树和B +树在构造和使用上比二叉树更接近。维基文章可以帮助清除定义-B + TreeB树二叉树
uutsav 2015年

1

B +树的一种可能用法是,它适用于树变得太大而无法容纳可用内存的情况。因此,您通常希望执行多个I / O。
即使确实在内存中使用了B +树,也经常会发生这种情况,然后您的缓存管理器可能会将其永久保存在内存中。但这是一种特殊情况,而不是一般情况,因此缓存策略与B +树维护是分开的。

同样,在B +树中,叶子页在链接列表(或双向链接列表)中链接在一起,从而优化了遍历(用于范围搜索,排序等)。因此,指针的数量是所使用的特定算法的函数。


这是对以下问题的回答:为什么我们不应该在所有地方都使用B树而不是B +树:)
堆栈程序员,

3
但是,据我们所知,您仅用您的答案描述了b树可能以完全相同的方式起作用。OP要求解释这些差异,而您仅谈论了一个,而没有谈论其他。你不能有一个圆圈的维恩图!
Malfist
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.