前篇提到B树及其实现:一文看懂---B树及其简单实现_b树实现_且随疾风前行->的博客-CSDN博客
本篇继续谈B树系列的B+树,B*树和它们与MySQL数据库的关系。
目录
B树系列
B+树
B+树的特性:
B*树
B树系列总结
MySQL索引简介
MyISAM
InnoDB
选择B+树
B树系列
B+树
1. 分支节点的子树指针与关键字个数相同2. 分支节点的子树指针p[i]指向关键字值大小在[k[i],k[i+1])区间之间,意味着最左边的子树被删除了,每个关键字下面的子树都是其右子树,也是下一个关键字的左子树关键点:3. 所有叶子节点增加一个链接指针链接在一起,这样方便遍历所有节点4. 所有关键字及其映射数据都在叶子节点出现,意味着 叶子节点的值和分支节点的值有重复,分支节点存的是叶子节点的索引,父亲节点存储是子树的最小值
B+树结构如图:
插入过程与B树基本类似,少许不同:
第一次插入的时候要插入两层节点,第一层作为索引,第二层作为叶子节点
后面往叶子插入的过程是一样的,插入满了之后分裂一半给兄弟,往父亲插入的是最小值
B+树的特性:
1. 所有关键字都出现在叶子节点的链表中,且链表中的节点都是有序的。2. 不可能在分支节点中命中。3. 分支节点相当于是叶子节点的索引,叶子节点才是存储数据的数据层。
B*树
B*树相当于是B+树的再变形,将分支节点用指针连接,并且规定每个节点关键字和孩子数量不少于最大数量的2/3。
B*树结构:
B*分裂规则:B*树的分裂,当一个节点满的时候,如果下一个兄弟节点没满,就将一部分数据移到兄弟节点中,再在原节点中插入关键字,最后修改父亲节点中兄弟节点的关键字,如果兄弟节点也满了,就在原节点与兄弟节点之间增加新的节点,并各自复制1/3的数据到新节点,然后在父节点增加新节点的指针。
所以B*树分配新节点的概率要比B+树低,空间使用率更高
B树系列总结
B树 有序数组+平衡多叉树
B+树 有序数组链表+平衡多叉树
B*树 一颗更丰满的,空间利用率更高(至少为2/3)的平衡多叉树
MySQL索引简介
MySQL是目前非常流行的开源关系型数据库,免费,可靠性高,速度快,有灵活的插件式存储引擎。
看上图可以看出数据库的底层是文件系统,使用C的API可创建套接字,连接数据库。
MySQL中索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的。
MyISAM
MyISAM引擎是MySQL5.5.8版本之前默认的存储引擎,不支持事务,支持全文索引,使用B+树做索引结构,叶节点data域存放数据记录的地址,存放地址,方便索引树和主键树映射同样的数据。
全文索引:通过关键字的匹配来查询过滤,基于相似度的查询,而不是精确数值比较
以Col1为主键,MyISAM的示意图:
特点:数据文件和索引文件分开存储,索引文件仅保存数据的地址
InnoDB
从MySQL数据库5.5.8版本开始,InnoDB存储引擎是默认的存储引擎。
特点:支持事务,面向在线事务处理的应用(内部实现了操作的原子性)支持B+树索引,哈希索引,全文索引使用B+树做索引时,实现方式与MyISAM不同:数据文件就是索引文件,辅助索引data域存储相应记录主键的值而不是地址按主键的搜索高效,但辅助索引搜索需检索两遍索引

可以看出叶节点包含了数据记录,这种索引方式称为聚集索引。

选择B+树
虽然分支节点只存储key,比较小,但也需要存磁盘中,因为数据量大了内存就存不下,KV结构中的value是存储一行数据的磁盘地址,分支节点映射的磁盘数据可以尽快加载到缓存中。
查找时:使用主键查找效率高:O(logn),直接遍历数据库效率低:O(n)。
创建索引时:相当于使用新的键值创建一棵新的B+树,value指向磁盘数据
相比B树的优势:
所有值都在叶子节点,方便遍历,方便区间查找
对于没有建立索引的字段,全表扫描的遍历方便
分支节点只存储键,分支节点占用空间更小,可以尽量更多地加载到缓存中
B树不用到叶子就能找到值,B+一定要查找到叶子节点,这是B树的一个优势,但是B+树的高度较低,所以二者在这点上差别不大。
注意:
一般数据库要求主键值是不重复的唯一值的字段,冗余时插入时就会报错,如果没有字段可以保持唯一,可以考虑自增主键。
一般数据库不要求索引唯一,MySQL数据库建立索引可以考虑B+树或者哈希表,数据允许冗余。