构建一个简单的数据库系列(七)引入B-tree

17 篇文章 1 订阅
5 篇文章 0 订阅

英文链接:https://cstack.github.io/db_tutorial/parts/part7.html

B-Tree是SQLite用来表示表和索引的数据结构,因此它是一个非常重要的想法。

为什么树对数据库来讲是非常合适的数据结构呢?

  • 搜索特定值很快(时间复杂度:对数)
  • 插入/删除您已经找到的值很快(重新平衡的时间是常量级的)
  • 遍历一系列值很快(与哈希映射不同)

 

 

example B-Tree (https://en.wikipedia.org/wiki/File:B-tree.svg)

批注:B-tree中的B是指balanced,而不是binary。后者是2叉树,每个节点最多只有2个子节点,而前者可以有2个以上的字节点,记为m,为了保持树大部分平衡,我们还说节点必须至少有m / 2个孩子(四舍五入)。

例外:

  • 叶节点有0个孩子
  • 根节点可以有少于m个子节点但必须至少有2个

上面的图片是一个B-Tree,SQLite用它来存储索引。为了存储表,SQLites使用称为B +树的变体。

 B-treeB+ tree
Pronounced“Bee Tree”“Bee Plus Tree”
Used to storeIndexesTables
Internal nodes store keysYesYes
Internal nodes store valuesYesNo
Number of children per nodeLessMore
Internal nodes vs. leaf nodesSame structureDifferent structur

 统一2个概念:

                Internal nodes:内部节点(分枝节点),即拥有孩子节点,leaf nodes:叶子节点,即没有孩子节点,区别如下:

For an order-m tree…Internal NodeLeaf Node
Storeskeys and pointers to childrenkeys and values
Number of keysup to m-1as many as will fit
Number of pointersnumber of keys + 1none
Number of valuesnonenumber of keys
Key purposeused for routingpaired with value
Stores values?NoYes

让我们通过一个例子来看看在插入元素时B树是如何增长的。为了简单起见,树将是订单3.这意味着:

  • 每个内部节点最多3个子节点
  • 每个内部节点最多2个key
  • 每个内部节点至少有2个子节点
  • 每个内部节点至少有一个key

空B树具有单个节点:根节点。根节点作为具有零键/值对的叶节点开始:

空的btree
空的btree

如果我们插入几个键/值对,它们将按排序顺序存储在叶节点中。

单节点btree
单节点btree

假设叶节点的容量是两个键/值对。当我们插入另一个时,我们必须拆分叶节点并在每个节点中放置一半对。两个节点都成为新内部节点的子节点,现在它将成为根节点。

两级btree
两级btree

内部节点有1个键和2个指向子节点的指针。如果我们想要查找小于或等于5的键,我们会查看左边的孩子。如果我们想要查找大于5的key,我们会找到右边的孩子。

现在让我们插入键“2”。首先,如果它存在,我们将查找它将在哪个叶节点,并且我们到达左叶节点。节点已满,因此我们拆分叶节点并在父节点中创建新条目。

四节点btree
四节点btree

让我们继续添加key。我们到了必须再次拆分的地步,但父节点中没有空间用于另一个键/指针对。

内部节点没有空间
内部节点没有空间

解决方案是将根节点拆分为两个内部节点,然后创建新的根节点作为其父节点。

三级btree
三级btree

当我们拆分根节点时,树的深度才会增加。每个叶节点具有相同的深度并且接近相同数量的键/值对,因此树保持平衡并且快速搜索。

在我们实现插入之后,我将推迟讨论从树中删除key的问题。

当我们实现这个数据结构时,每个节点将对应一个页面。根节点将存在于第0页中。子指针将只是包含子节点的页码。

下一次,我们开始实施btree!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值