数据结构与算法--B+树看它就够了

1,348 阅读2分钟

[TOC]

B+树

​ 对于数据库,我们主要做到三点:查询效率高、减少内存耗费、支持区间查找,通过改造二叉查找树,我们发明了B+树来存储数据库的索引

支持区间查找

树中节点只作为索引,每个叶子节点串在一条双向链表上,这样我们想要查询某个区间,只需要找到最小值,然后通过链表遍历即可。

减少内存耗费

​ 上图中每个节点至少占用索引值+两个指针那么大内存,如果十亿个节点(20GB)计算机很可能装不下。

​ 我们可以通过把索引存储在磁盘上解决内存耗费问题

查询效率高

​ 通过把索引存储在磁盘上解决了内存耗费问题,但相应的效率就会降低(内存访问速度是磁盘的上万倍)

​ 为了减少磁盘访问次数(也就是磁盘IO操作),我们就需要降低树的高度(因为每查询一个节点都需要访问一次磁盘,高度降低了,找到对应叶子节点需要的IO操作也就降低了),所以我们可以把二叉树改为多叉树

叉数并不是越多越好,我们知道磁盘中的数据都是按页读取的(一页4kb),也就是说一次IO操作最多读取4kb数据,因此我们要保证节点小于4kb

​ 假设是m叉数,每个内部节点需要存储m-1个键值(用来划分区间)和m个指针,而叶子节点只需存储数据和前后链表指针

B+树索引的插入和删除调整

插入调整:对于m叉树,叶子节点超过m-1个就分裂;非叶子节点超过m个指针就分裂

删除调整:对于m叉树,如果某个节点的子节点个数小于 m/2,我们就将它跟相邻兄弟节点合并(如果合并后大于m则再分裂)

总结

  • m 叉树只存储索引,并不真正存储数据;
  • 通过链表将叶子节点串联在一起,这样可以方便按区间查找;
  • 一般情况下根节点存储在内存中,其他节点存储在磁盘;
  • 插入调整:对于m叉树,叶子节点超过m-1个就分裂;非叶子节点超过m个指针就分裂(插入调整目的是为了避免一个节点超过4kb导致性能下降)
  • 删除调整:对于m叉树,如果某个节点的子节点个数小于 m/2,我们就将它跟相邻兄弟节点合并,如果合并后大于m则再分裂(删除调整目的是为了避免树过高)