B-树的变种B+/B*树
展开分析,以及MySQL数据库的两个引擎MyISAM与InnoDB作以阐述,文中引入了部分网上资料。
B+树作为B-树的一个变种,也是一种多路搜索树
。其定义基本与B-树没有区别
,除了以下几点:
1)非叶子结点的子树指针域关键字个数相同。
2)非叶子结点的子树指针P[i],指向关键字属于([K[i],K[i+1]])的子树(B-树是开区间)。
3)它为所有叶子结点增加了一个链指针。
4)所有的关键字都在叶子结点出现。
B+树的搜索与B-树也基本相同,区别
在于B+树只有到达叶子结点才能被命中
,而B-树可以在非叶子结点被命中
,其性能也等价
于在关键字全集做了一次二分查找
。
① 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的。
② 不可能在非叶子结点命中。
③ 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层。
④ B+树更适合做文件系统。
在B+树上进行随机查找、插入和删除
基本与B-树类似,不同之处在于:
B+树在查找时
:若非终端结点上的关键字等于给定值
,并不终止
,而是继续向下
直到叶子结点。因此,在B+树中查找无论成功与否,都会走到叶子节点。
B+树在插入时
:仅在叶子结点上进行
,当结点中的关键字个数大于M时要分裂成两个节点,它们所包含的关键字个数分别为[(M+1)/2]和[(M+1)/2],并且它们的双亲结点中应包含这两个节点中的最小/大关键字。
B+树在删除时
:仅在叶子结点上进行
,当叶子结点中的最小/大关键字被删除时,并在非终端结点中的值可以作为一个分界关键字存在。若因删除而使节点中关键字小于[M/2]时,其和兄弟节点的合并过程与B-树类似。
B*树是B-树的二次变种,即·在B+树的非根和非叶子结点增加了指向兄弟的指针·。它的图示如下:
*B*树定义了非叶子结点关键字个数至少为(2/3)M,即块的最低使用率为2/3(代替B+树的1/2)。
对上面的解释为
:B*树插入时,当一个节点满时,如果它的下一个兄弟节点未满,那么将一部分数据移到兄弟节点中,再在原节点插入关键字,最后修改父节点中兄弟节点的关键字(因为兄弟节点的关键字范围改变了)。如果兄弟节点满了,则在原节点与兄弟节点之间增加新节点,并各复制1/3的数据到新节点,最后在父节点增加新节点的指针。
B- 树
:多路搜索树
,每个节点存储M/2到M
个关键字,非叶子节点存储
指向关键字范围的子节点。B+树
:在B-树的基础上为叶子结点增加了链表指针
,所有关键字都在叶子结点出现,非叶子节点作为叶子结点的索引
,且只能在叶子结点才能够被命中
。
B* 树
:在B+树的基础上,为非根非叶子结点增加链表指针
,将节点的最低利用率从1/2提高到2/3。
目前大多数的数据库系统
及文件系统
都采用B-Tree
及其变种B+Tree
作为索引结构
,虽然RB-Tree
也可以用来实现索引,但是依据 计算机的局部性原理 ,采用B-/+Tree可以减少查找过程中磁盘I/O的存取次数
,从而提高效率。
▶MyISAM索引实现(非聚集)
MyISAM引擎使用B+Tree
作为索引结构,叶节点的data域存放的是数据记录的地址(B+Tree中,key是表主键,value是数据在磁盘中的地址)。下图是MyIASM的原理图:
上述表中共有三列,假设Col1为主键,可以看出MyISAM的索引文件仅仅保存数据记录的地址,在MyISAM中,主索引与辅助索引在结构上没有任何区别,只是主索引要求key唯一,而辅助索引可以重复。
MyISAM索引检查的算法
为首先按照B+Tree搜索算法搜索索引,如果key存在,则去除其data域的值,然后以data域的值为地址,读取相应的数据记录。
▶InnoDB索引实现(聚集)
虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。原理图如下:
InnoDB与MyISAM的主要区别在于:
1)事务处理方面
:MyISAM强调的是性能,查询的速度比InnoDB更快,但是不提供事务支持。
2)外键方面
:MyISAM不支持外键,但InnoDB支持外键。
3)锁机制方面
:MyISAM只支持表级锁,InnoDB支持行级锁和表级锁,默认为行级锁。
4)全文索引方面
:MyISAM支持全文索引,InnoDB不支持全文索引。InnoDB从MySQL5.6版本开始提供全文索引。
5)表主键方面
:MyISAM允许没有主键的表存在。InnoDB如果没有设定主键,就会自动生成一个6字节的主键(用户不可见)。
6)表的具体行数
:MyISAM只要简单的读出保存好的行数,因为它内置了一个计数器,count(*)时它直接从计数器中读。InnoDB不保存表的具体行数,需要扫描一遍整个表来计算有多少行。
① InnoDB的数据文件本身就是索引文件,而MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而InnoDB的叶节点保存了完整的数据记录。
② InnoDB的辅助索引data域存储相应记录主键的值而不是地址,即InnoDB的索引辅助索引都引用主键作为data域。
聚集索引
这种实现方式使得按主键的搜索十分高效
,但是辅助索引
搜索需要检索两遍索引
:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
参考博客:
Mysql为啥用B+