B树B+树以及基于B+树的数据库引擎特点

B树(B-Tree)

一个m阶B树特点

  • 每个结点至多拥有m棵子树

  • 根节点至少拥有两颗子树(存在子树的情况下),根节点至少有一个关键字

  • 除了根节点以外,其余每个分支节点至少有m/2棵子树

  • 所有的叶子节点都在同一层上,B树的叶子节点可以看成是一种外部节点,不包含任何信息

  • 有k棵子树的分支节点则存在k-1个关键码,关键码按照递增次序进行排列

  • 关键码数量需满足cell(m/2) - 1<= n  <= m - 1

cell()向上取整    floor()向下取整

 

特性:利用平衡树的优势,保证了查询的稳定性和加快了查询的速度

出现多路查找树的数据结构,用在内存读取外存的场景下,可以减少磁盘的IO次数,因为在高阶的情况下,树不要很高就可以标识很大的数据量

B树详解:https://www.cnblogs.com/George1994/p/7008732.html

插入

通过搜索找到对应的结点进行插入,根据即将插入的结点的数量分为以下几种情况

  • 如果该结点的关键字个数没有达到m-1个,那么直接插入

  • 如果该结点的关键字个数已经到达了m-1个,那么根据B树的性质显然无法满足,需要将其进行分裂。分裂规则是该结点分成两半,将中间的关键字进行提升,加入到父亲节点中,但是这又可能存在父亲结点也满员的情况,则不得不向上进行回溯,甚至是要对根结点进行分裂,那么整棵树都加了一层

 

 

删除

同样的,我们需要先通过搜索找到相应的值,存在则进行删除,需要考虑删除以后的情况

  • 如果该结点拥有的关键字数量仍然满足B树性质,则不做任何处理

  • 如果该结点在删除关键字以后不满足B树的性质(关键字没有达到cell(m/2)-1的数量),则需要向兄弟结点借关键字,这又分为兄弟结点的关键字数量是否足够的情况

  1. 如果兄弟结点的关键字足够借给该结点,则将父亲结点的关键字下移,兄弟结点的关键字上移

  2. 如果兄弟结点的关键字在借出去以后也无法满足B树性质,即之前兄弟结点的关键字的数量为cell(m/2)-1,借的一方的关键字数量为cell(m/2)-2的时候,我们可以将结点合并到兄弟结点中,合并之后的子结点数量少了一个,则需要将父亲结点的关键字下放,如果父亲结点不满足性质,则向上回溯

 

B+树

操作

其操作被B树的操作是类似的,不过需要注意的是,在增加的时候,如果存在满员的情况,将选择结点中的值作为新的索引。还有在删除值的时候,索引中的关键字并不会删除,也不会存在父亲结点关键字下沉得的情况,因为仅仅是索引

 

B树和B+树的区别

以一个m阶树为例

  • 关键字的数量不同;B+树分支结点中有m个关键字,其叶子结点也有m个,其关键字只是起到了一个索引的作用,虽然B树也有m个子结点,但是其只拥有m-1个关键字

  • 存储的位置不同;B+树中的数据都存储在叶子结点上,也就是其所有叶子结点的数据组合起来就是完整的数据,但是B树的数据存储在每一个结点中,并不仅仅存储在叶子结点上

  • 分支结点的构造不同;B+树的分支结构存储着关键字信息和儿子指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息(非叶子节点的子树指针p[i],指向关键字属于【k[i],k[i + 1]】的子树)

  • 查询不同;B树在找到具体的数值以后就结束,而B+树则需要通过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程中走了一条从根结点到叶子结点的路径,其高度是相同的,相对来说更加的稳定(更适合文件索引系统)

  • 区间访问;B+树的叶子结点会按照顺序建立起链状指针,可以进行区间访问

 

B*树

B*树是B+树的变形,在B+树的非根和非叶子节点再增加指向兄弟节点的指针

  • B*树定义了非叶子节点的关键字个数至少为(2/3)*M,则块的最低使用率为2/3(代替B+树的1/2)

  • B*树的分裂,当一个结点满的时候,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父节点中兄弟结点的关键字(因为兄弟结点关键字的范围改变了);如果兄弟结点也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在 父节点增加新结点的指针

  • B*树分配新结点的概率比B+树要低,空间使用率更高

 

MySQL索引结构

B+树最常见的应用就是用来索引,索引是帮助MySQL高效获取数据的数据结构

MyISAM存储引擎(5.5.8版本之前)

Mysql会在你配置的数据目录下生成3个文件——hiro.MYD(存储数据)、hiro.MYI(存储索引)、hiro.frm(存储表结构)——文件存储提供了更好的跨平台性

Mysql支持三种不同的存储格式——动态的,固定的,压缩的

索引文件(.MYI):包括头部信息和索引值,头部文件记录了索引选项、索引文件大小和索引定义

该引擎为MySQL默认引擎,但是未提供对数据库事务的支持,也不支持行级锁和外键,在更新和插入的时候需要锁定整个表,所以效率较低

索引特色:MyISAM使用B+树作为索引结构,叶结点的data域放的是数据记录的地址,在MyISAM中,主索引和辅助索引在结构上没有任何区别,只是主索引要求key是唯一 的,而辅助索引的key可以重复

 

InnoDB存储引擎(5.5.8版本之后)

InnoDB给MySQL提供了具有可回滚和防崩溃能力的事务型存储引擎——保证了事务安全

在SELECT语句下提供了MVCC(多版本并发控制),还支持外键功能,在SQL查询中可以将InnoDB类型的表和其他MySQL的表混合。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用InnoDB引擎会提升效率,但是使用行级锁也不是绝对的,如果执行SQL语句时不能确定要扫描的范围,InnoDB表同样会锁全表

索引特色:

  • InnodeDB的数据文件本身就是索引文件,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址,而InnoDB索引,表数据文件就是按B+Tree组织的一个索引结构,这棵树的叶子节点data域保存了完整的数据记录(聚集索引)

  • 因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求必须有主键(没有显式指定则系统自动标识一个能够唯一标识数据记录的列作为主键,不存在则自动生成一个6B的隐含字段)

  • InnodeDB的辅助索引data域存储相应记录主键而不是地址(辅助索引搜索需要检索两遍索引,首先检索辅助索引获得主键然后用主键到主索引中检索获得记录)

 

 

应用场景:

  • MyISAM管理非事务表,提供高速存储和检索以及全文搜索能力,如果应用中执行大量的select操作,应该选择MyISAM

  • InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,应该选择InnoDB

 

MySQL使用的是B+树来存储索引的,为什么不用其他的数据结构呢?

二叉树->根据二叉树的概念,当数据是递增的时候,它的节点会一直增大下去

红黑树->平衡二叉树->每个节点存一个值,同样会导致节点过多

B树->每个节点可存放多个值(解决红黑树高度过大的问题),但是涉及到范围查询的时候同样不占优势

B+树->叶子节点有指针相连(方便范围查询)

你可能感兴趣的:(MySQL)