B树的进化版----B+树
C++为什么叫C plus plus?
这是由于C++相当于继承C的语法后,增加了各方面的能力,所扩展出的一种新语法。
在软件领域中 plus 有增加的味道。在这里B +树也一样,是B树的增强版。
在学习B+树之前,最好是对B树有一定的了解。不了解的各位也没有关系,可以花费5分钟的时间读我的上一篇文章《数据库索引的基石----B树》。
我在上篇文章的最后,专门提到,由于B树的设计,导致它存在一种天然的劣势,导致典型的B树在很多方面受到了限制。
这个劣势是什么呢?(自问)
先想下,为啥我们在类磁盘的数据查找系统中,并没有使用高效的平衡二叉查找树,而设计出了B树?这是由于B树是考虑到了加载硬盘数据到内存是系统瓶颈,所以让节点变重,承载更多的关键字。但是B树在设计时,为了查找方便,节点信息除了包含关键字,还包含了data信息,这就导致每个节点所能包含的最大关键字个数被压缩了。(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )这就导致最终并没有达到每次次加载,加载的关键字是最大数目的最优方案。(自答)
基于这个原因,有人对B树进行了改良,提出了B+树(B plus tree)。
也就是下边这个样子

根据B+树的图,我们可以轻易总结出以下几个不同点:
1、 在B+树中,如果一个节点包含n个关键字,那么他就有n个分支。
在B树中,含有n个关键字的节点有n+1个分支。
也就是说B+树是一个关键字对应一个分支,B树是一个关键字的空位置对应一个分支。
2、 B+树中节点的关键字个数范围比对应的B树多1。
3、 B+树的叶子节点包含全部关键字,叶子节点的指针指向关键字对应的数据。
4、 B+树的所有非叶子节点仅仅起到一个索引的作用,即节点中的每个索引项只含有对应子树的最大关键字和指向该子树的指针。不含有该关键字的所对应的数据。
在B树中,每个节点还会额外记录关键字所对应的数据。
5、 B+树中存在一个额外的指针,这个指针指向于包含最小关键字的节点。然后所有的叶子节点从小到大的串联起来,形成一个线性的链表。
最主要的不同点是4、5两点,这里着重解释下第4点:
父节点中关键字的位置是其子节点中所有的关键字中的最大值。
如图中62是子节点(56,62)的最大值96是子节点(62,78,96)的最大值。
96存在于三个节点中,但是它对应的数据只存储在叶子节点中。
而B树如果是相同数据的话,96只会存在一个节点中,而这个节点直接就包含了96对应的数据。
正是由于第4点导致了B+树的查找,系统每次可以从磁盘中加载的数据量更大,调用的IO耗时更少。
而由于第5点的存在,导致B+树在范围查找等方面有了极大的优势。
下边结合上边的B+树,我们来举几个例子:
(1) 查找15
首先加载根节点(50,96),依次比较,发现15≤ 50,匹配成功。
加载50对应的子节点(15,50)。依次比较,发现15=15,匹配成功。
加载15对应的子节点(3,8,15)。依次比较,发现15=15,匹配成功。
由于(3,8,15)是叶子节点,所以可以直接取出对应数据。
(2)查找14
前边都相同,直至加载叶子节点(3,8,15)。
依次比较3,8,不匹配,比较15,发现14<15,并且当前节点是叶子节点,所以匹配失败,B+树不包含14关键字。
(3)查找满足14≤x≤57条件的所有x
同(2)场景,发现14不存在,15是满足条件的最小值,存储15。
加载下一个叶子节点(20,26,27,50),依次比较发现都满足,全部存储。
加载下一个叶子节点(56,62),依次比较发现56满足条件,62超出范围,存储56。
最终得出满足条件的所有数据是{15,20,26,27,50,56}。
由于B+树的种种优势,使得其被广泛应用于各种文件查找系统中,如mysql、MongoDB。在mysql中,你在建立索引所选取的B树,底层的实现正式B+树。另外MongoDB在官方文档中描述,索引使用B树,于是很多文章甚至面试官就想当然的提问,为什么MongoDB没使用B+树,而是使用的B树。其实作者曾经就已作出澄清,底层的实现使用的是B+树。(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )而文档写为B树,我们可以理解为B+树是B树的一个增强版。(此处可参考https://q.cnblogs.com/q/127244/)所以当有人问你,为什么mysql使用B+树,而MongoDB使用B树时,你可以给他一个惊喜。
B树的进化版----B+树的更多相关文章
- 【Uvalive4960】 Sensor network (苗条树,进化版)
[题意] 给出N个点,M条边,问这N个点形成的生成树的最大权值边-最小权值边的最小值 InputThe input consists of several test cases, separated ...
- [转载]完全版线段树 by notonlysuccess大牛
原文出处:http://www.notonlysuccess.com/ (好像现在这个博客已经挂掉了,在网上找到的全部都是转载) 今天在清北学堂听课,听到了一些很令人吃惊的消息.至于这消息具体是啥,等 ...
- SQL优化 MySQL版 - B树索引详讲
SQL优化 MySQL版 - -B树索引详讲 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 为什么要进行SQL优化呢?很显然,当我们去写sql语句时: 1会发现性能低 2.执行时间太 ...
- P3379 【模板】最近公共祖先(LCA)(树链剖分)版
#include <bits/stdc++.h> #define read read() #define up(i,l,r) for(register int i = (l);i < ...
- 《完全版线段树》——notonlysuccess
转载自:NotOnlySuccess的博客 [完全版]线段树 很早前写的那篇线段树专辑至今一直是本博客阅读点击量最大的一片文章,当时觉得挺自豪的,还去pku打广告,但是现在我自己都不太好意思去看那篇文 ...
- 【转载】完全版线段树 by notonlysuccess大牛
原文出处:http://www.notonlysuccess.com/ 今晚上比赛就考到了 排兵布阵啊,难受. [完全版]线段树 很早前写的那篇线段树专辑至今一直是本博客阅读点击量最大的一片文章,当时 ...
- 洛谷——P1276 校门外的树(增强版)
P1276 校门外的树(增强版) 题目描述 校门外马路上本来从编号0到L,每一编号的位置都有1棵树.有砍树者每次从编号A到B处连续砍掉每1棵树,就连树苗也不放过(记 0 A B ,含A和B):幸运的是 ...
- HDU 1166.敌兵布阵-完全版线段树(单点增减、区间求和)
生活艰辛,且行且珍惜. 先水一篇博客再去补题,要不然又忘记写博客了. 计划系统的刷一遍线段树专题,自己给自己找虐(自作孽不可活),从基础的到后面的,所有的都挂了题,刷题不,大兄弟? 线段树可真有意思, ...
- Luogu P1276 校门外的树(增强版)
Luogu P1276 校门外的树(增强版) 本来看着是道普及-,就不打算写博客了,结果因为出了3次错,调试了15min就还是决定写一下-- 本题坑点: 1.每个位置有三种情况:空穴,树苗,树(而不只 ...
随机推荐
- 本科入行可能吗?做到这3点,斩获BAT offer不是梦
大家好,前两天有一个小伙伴加我微信咨询.他说他不想读研,想要直接本科毕业就参与工作.但是又担心自己由于没有学历优势,无法在校招当中获得机会,于是便来向我请教,能不能指点迷津提供一些具体的实操性措施.与 ...
- python脚本乱码的解决方法
使用python2 在windows cmd 执行python脚本发生乱码的解决方法 可以先把中文解码为unicode,然后再转化为gbk显示正常,需要在代码打印中文处添加 print(':这是一段中 ...
- Mysql5.7.20安装手记
Mysql到5.7之后安装较之前有了很大的不同,特别是解压缩版,可能安装速度较之前有所减少,但对于我们这种一直使用5.5的我来说不知道步骤还真是挺费劲的.下面详细记一下我安装的过程. 1.下载mysq ...
- 关于git中的merge和rebase
变基-git官网说明 变基 改变提交的基于分支 和merge不同 合并显示合并记录 变基合并更新后一起提交 不显示合并记录 变基 合并的结果是一致的
- 简单web页面第一步---表单
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncod ...
- java键盘输入方法-
字符串缓冲方式 BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); String line = null ...
- 本地项目上传至GitHub
本地项目上传至GitHub 使用git上传 一.安装git 直接官网下载,安装即可. git官网下载 github下载 按照好后大概就是这个样子 二.创建公钥和私钥 有的就可跳过此步骤 我们双击打开g ...
- 进程描述符(PCB)
进程描述符(PCB) 概述 CPU作为计算机的核心部件,我们当然希望它能一直工作,充分提高它的使用效率.对于上层软件来说,我们不可能直接去操控CPU(我们没这能力也没必要),因为操作系统是夹在计算机硬 ...
- 多线程,线程类三种方式,线程调度,线程同步,死锁,线程间的通信,阻塞队列,wait和sleep区别?
重难点梳理 知识点梳理 学习目标 1.能够知道什么是进程什么是线程(进程和线程的概述,多进程和多线程的意义) 2.能够掌握线程常见API的使用 3.能够理解什么是线程安全问题 4.能够知道什么是锁 5 ...
- 搭建 Typecho 个人博客
搭建 Typecho 个人博客 前言 最近在学习中,感觉有个自己的博客,用来记录学习总结,写写生活点滴是件不错的事. 在网上看到 Typecho 博客和 WordPress博客,顿时被 Typecho ...