7.4.2B+树
B+树:
(1)每个分支节点最多有m个子树(孩子节点)。
阶:即看当前的B+树是几阶B+树,就看每个分支节点最多有几个子树,还是看最下一层有几个分叉就是几阶???
叶子节点:最下边的一层叫叶子节点(不是跟B树一样的失败节点)
非叶根节点:当前的B+树中根节点下边还有子节点,即根节点不是最下边的一层节点(叶子节点),则当前的根节点叫非叶子节点的根节点,即非叶根节点。
叶根节点:当前的B+树只有一层,即只有一层根节点,根节点下边再没有子树节点,则当前的根节点也是叶子节点(如图2中的左一)
(2)非叶根节点至少有2棵子树,其他每个分支节点至少有m/2向上取整个子树,前者是为了让B+树尽可能的低,使查找效率高一点,所以要保持绝对平衡,即假如当前的根节点是非叶根节点,它如果有左子树,则它必定有右子树,否则不满足B+树要求(如图2中的中间的图),后者是为了让B+树的每个节点上的关键字尽可能的多,也是为了保证B+树的高度没那么高,提高查找效率
(3)节点的子树个数与关键字的个数相等。即一个节点上有几个关键字,则它就有几个分叉,即就有几个子树,如(3,9,15)节点上有3个关键字,则它就有3个分叉,即3个子树,(1,3)(6,8,9)(13,15)。注意与B树区分,B树上一个节点上有2个关键字它得有3个分叉,即3个子树
(4)叶节点包含以上成所有的关键字+指向相应记录的指针,叶节点中的关键字按大小顺序排列,相邻叶节点按大小顺序相互链接起来,即叶节点那一层支持横向顺序查找。每个关键字对应了一个指向详细记录的指针(如叶节点的关键字是一个个学号,学号连接着每个学生的具体信息,即学号连接着记录)
(5)跟分块查找的索引表类似,所有分支节点上的各个关键字都只包含了关键字指向子节点上的所有关键字的最大值。比如(3,9,15)中的3就是它的子节点(1,3)中关键字最大值,9是子节点(6,8,9)中的最大值,15是子节点(13,15)的最大值
对比分块查找:
B+树的查找:
查找成功目标元素9(实际查找的是9所指的记录): 从根节点开始找,第一个关键字15是它所有的子节点(所有的子节点指的是它的整个左子树节点,包括子节点和孙子节点等待)中最大的关键字的值,15>9则如果目标元素存在,则它只能在15所指向的分块中,让指针指向下一级节点3,3是它所指的分块中最大的关键字,3<9则9肯定不在3所指的分块里,让指针右移指向9,9==9,则在9所指的分块里,让指针下移,从左往右开始比较叶子节点,直到找到9==9,则9关键字所保存指针信息就可以找到9号元素的详细记录信息,进而读出相应记录
查找失败目标元素7(实际查找的是7所指的记录): 从根节点开始找,15>7则如果目标元素存在,则它只能在15所指向的分块中,让指针指向下一级节点3,3<7则7肯定不在3所指的分块中,让指针右移9,7<9则如果7存在7一定在9所指的分块中,让指针下移指向(6,8,9)节点,从左往右开始比较叶子节点,6<7指针右移,7<8,因为已经找的是最下一层的叶子节点了,如果没找到7证明7不存在,则查找失败
无论查找成功还是失败都要走到最下一层即叶子节点处才能确定到底是否查找成功,因为分支节点上的范围并不是实际的关键字,实际有哪些关键字其实是在叶子节点存放,但是B树查找不是,可能停留在任何一层就能知道 是否能查找成功了。
B+树VSB树:
m阶B树:
(1)节点中的n个关键字对应n+1个分叉,即n+1个子树
(2)B树中为了保证树不太高,节点上的关键字不太空,所以要求B树中的根节点的关键字个数不能少于1个,即根节点关键字个数范围(1,m-1)【根节点中最多的关键字个数和其他节点的关键字个数最多一样】,其他节点的分叉不能少于m/2向上取整,则关键字个数不能少于m/2向上取整-1个,对于m阶B树,则每个节点的最多分叉有m个,即最多的关键字个数有m-1个,即其他节点的关键字个数范围(m/2向上取整-1,m-1)
(3)在B树中,各个节点包含的关键字是不会重复出现的
(4)B树中的各个关键字也存储了实际关键字对应的记录存储地址,即不用找到叶子节点,只要找到了这个关键字就相当于找到了记录存储地址即记录信息,但是B+树不行,B+树一定要在叶子节点上找到了这个关键字,才能找到这个关键字的存储记录的地址,才能找到实际存放的数据信息
m阶B+树:
(1)节点中的n个关键字对应n个分叉,即n个子树
(2)B+树中为了保证树不太高,节点上的关键字不太空,所以要求B+树中的根节点的关键字个数不能少于1个,即根节点关键字个数范围(1,m)【根节点中最多的关键字个数和其他节点的关键字个数最多一样】,其他节点的分叉不能少于m/2,则关键字个数不能少于m/2向上取整个,对于m阶B+树,则每个节点的最多分叉有m个,即最多的关键字个数有m个,即其他节点关键字个数范围为(m/2,m)
(3)B+树叶子节点中包含全部的关键字,则某个关键字可能会在其他非叶子节点多次出现,如下图2中的15关键字在3处出现
(4)在B树中,所有非叶子节点仅起到索引查找作用,实际并不包含目标元素记录的存储地址,而只有找到叶子节点了,才能找到该关键字对应记录的存储记录,如学生信息,学生信息是记录,关键字是学号,一个学号对应一个学生记录。非叶子节点的每个索引项(指非叶子节点中的关键字)只包含了子树的最大关键字和指向该子树的指针
B+树中的各个节点存储在磁盘,操作系统对磁盘的读写一般是以一个磁盘块为单位,一般B+树的一个节点就会存储在某个磁盘块中,即B+树中所有的节点都是存储在不同的磁盘块里,因此从根节点开始查找,会先确定根节点到底在哪个磁盘块中,然后把根节点所在的磁盘块读入内存,即把(15,56)所在磁盘块读入内存,读入内存之后计算机就可以处理查询数据,就可以知道要去哪个分支去找,比如要找关键字42,在读入内存之后就知道要去56指向的分块去找,现在知道了56所指的分块存储在磁盘什么位置之后,就会把56所指的分块读入内存,即(35,42,56)读入内存后,九三级去查询分块内的数据,然后计算机发现42存储在42所指的分块中,然后通过内存中的信息就可以知道,42所指的叶子节点存储在磁盘的哪个位置,然后操作系统再把42所指的分块读入内存,读入内存之后就可以知道42这个关键字它所对应的记录到底存储在磁盘的哪个位置,然后再把记录读入内存。磁盘是一个慢速设备,每次要读取磁盘块数据都会花费大量时间,因此假如B+树高度越高就意味着在读取磁盘的过程中读取次数越多,导致查找速度更慢,如何降低B+树高度,即让B+树节点存储更多的关键字,即这也是为什么B+树上的非叶子节点不存储实际的记录地址了,这样能节省更多的空间来存储关键字,并且这些一个个节点是存储在每个磁盘块中,而每个磁盘块大小基本固定如1kb,而让每个磁盘块包含尽可能多的关键字的信息,当节点的空间大了则每个节点存储的关键字就多了,则磁盘上就包含了尽可能多的关键字信息了。。。。。。,即每个关键字不存储记录指针,会让关键字更多,即分叉更多,即B+树的高度越矮,即读取磁盘的次数减少,即效率更高。B树的一个关键字中还包含了记录的存储地址,这就意味着一个节点存储的关键字就会少,这也就意味着磁盘块中存储的节点上的关键字就会少,则B树会导致磁盘块读取次数增多,而磁盘块读取又耗时,则会降低效率
知识回顾:
好罗里吧嗦。。。。。。。。。。。。。。。。。。。。。