一、B+树是应文件系统所需而产生的一种B树的变形树

1. 定义(使用阶数m来定义)

  1. 除了根结点外,其他非终端结点最多有m个关键字,最少有⌈m/2⌉个关键字
  2. 结点中的每个关键字对应一个子树
  3. 所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字
  4. 所有的叶子节点包含了全部的关键字以及指向含有这些关键字记录的指针,并且:

    • 同一叶子节点中的关键字按大小顺序排列
    • 相邻的叶子节点顺序链接(相当于是构成了一个顺序链表)
    • 所有叶子节点在同一层

2. 和B树的区别

对于非终端结点,关键字的个数与其子树的个数相同;不像B树,子树的个数总比关键字的个数多1。

所有的关键字及相应的指针都在叶子结点中;不像B树,有的关键字是在内部结点中。(换句话说,在B+树中,内部结点仅仅起到索引的作用。在搜索过程中,如果待查询的关键字和内部结点的关键字一致,那么搜索过程不停止,而是继续向下搜索这个分支)

  1. 关键字的数量不同:B+树中,对于非终端结点,关键字的个数与其子树的个数相同;而B树中,关键字的个数比子树的个数少1。
  2. 存储的位置不同:B+树中的数据都存储在叶子结点上,也就是其所有叶子结点的数据组合起来就是完整的数据;而B树的数据存储在每一个结点中。
  3. 非终端结点的构造不同:B+树的非终端结点仅仅存储着关键字信息和指向孩子的指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息。
  4. 查询不同:B树在找到具体的数值以后,则结束;而B+树则需要通过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程中走了一条从根结点到叶子结点的路径。

二、关于B+树的面试题

1. 为何B+树用于数据库索引?

B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B树的其非终端结点同样存储着数据,因此如果我们要找到具体的数据,就需要进行一次中序遍历。正是为了解决这个问题,B+树应运而生。

B+树的数据都存储在叶子结点中,非终端结点均为索引,方便扫库,只需要遍历叶子结点即可实现整棵树的遍历。所以B+树更加适合在区间查询的情况,而且在数据库中基于范围的查询是非常频繁的,所以通常B+树用于数据库索引。

2. 为何相比于B树,B+树在文件系统和数据库系统中更具优势?

①B+树的磁盘读写代价更低 
B+树的非终端结点并没有指向关键字具体信息的指针,因此其内部结点相对B树更小。如果把同一非终端结点的所有关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说I/O读写次数也就降低了。

举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B树(一个结点最多8个关键字)的非终端结点需要2个盘快。而B+树非终端结点只需要1个盘快。当需要把非终端结点读入内存中的时候,B树就比B+树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。

②B+树的查询效率更加稳定 
由于非终端结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路径。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

③B+树更有利于对数据库的扫描 
B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题,而B+树只需要遍历叶子节点就可以解决对全部关键字信息的扫描,所以对于数据库中频繁使用的范围查询,B+树有着更高的性能。

7. B+树的更多相关文章

  1. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  2. ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单

    前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...

  3. 再讲IQueryable<T>,揭开表达式树的神秘面纱

    接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...

  4. HDU1671——前缀树的一点感触

    题目http://acm.hdu.edu.cn/showproblem.php?pid=1671 题目本身不难,一棵前缀树OK,但是前两次提交都没有成功. 第一次Memory Limit Exceed ...

  5. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  6. [C#] C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  7. bzoj3207--Hash+主席树

    题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...

  8. bzoj1901--树状数组套主席树

    树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...

  9. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  10. jquery-treegrid树状表格的使用(.Net平台)

    上一篇介绍了DataTable,这一篇在DT的基础之上再使用jquery的一款插件:treegrid,官网地址:http://maxazan.github.io/jquery-treegrid/ 一. ...

随机推荐

  1. 纯javascript实现选择框的全选与反选

    HTML部分 <div id="wrap_input_box" > <input type="checkbox"><br> ...

  2. mac 装5.6版本mysql 设置密码

    最的mysql在装的时候就可以设置 ,但是低版本的好像不行,需要在装了以后才能设置. mac下,mysql5.7.18连接出错,错误信息为:Access denied for user 'root'@ ...

  3. Linux基础-4.正文处理命令及tar命令

    1.使用cat命令进行文件的纵向合并 1)掌握使用cat命令的纵向合并 a)例如:使用cat命令将test1.file1.txt和file2这三个文件纵向合并为file文件的命令为: cat test ...

  4. jquery里操作json相关的方法和实例

    $.getJSON("/html/aijquery/JSON.js",function(d){     $.each(d,function(i,v){             $( ...

  5. MongoDB数据库 : 管道,用户管理,副本集等

    聚合(aggregate): db.集合.aggregate([{管道:{表达式}}]) db.集合.aggregate([ {管道1:{表达式1}}, {管道2:{表达式2}}, ... ...]) ...

  6. 智能家居系统 Home Assistant 系列 --介绍篇

    一. HomeAssistant 是什么? HomeAssistant是构建智慧空间的神器.是一个成熟完整的基于 Python 的智能家居系统,设备支持度高,支持自动化(Automation).群组化 ...

  7. nRF52832 BLE_DFU空中升级OTA(一)安装软件(SDK14.2.0)

    准备工作,需要安装好几个软件,详细的过程请参考下面的文章(http://www.cnblogs.com/iini/p/9314246.html)这里说的非常详细,而且也有工具在云盘,对于初学者非常友好 ...

  8. Go黑帽子

    使用go语言来实现python黑帽子和绝技的代码 1.unix密码破解器 package main import( "bufio" "flag" "i ...

  9. ECShop全系列版本远程代码执行漏洞复现

    前言 问题发生在user.php的display函数,模版变量可控,导致注入,配合注入可达到远程代码执行 漏洞分析 0x01-SQL注入 先看user.php $back_act变量来源于HTTP_R ...

  10. 检测com端口代码实现

    1:scan HRESULT CDevHound::Scan(const vector<CString> &guiInfo, vector<DEV_INFO> & ...