关于MySQL中索引底层数据结构B树和B+树的理解以及常见问题

在说B树之前我们首先需要知道平衡二叉树这个概念,所谓平衡二叉树(如果不是一颗空树)那么它左右两个子树的高度差的绝对值不超过1,并且左右两个子树也都是一棵平衡二叉树。

B树与B+树

B树就相当于一个平衡多叉树。那么它就有以下性质:

  1. 这种树的每个节点不限于两个孩子,n阶B树那么其每个节点就有n个孩子
  2. 除了根节点和叶子结点外,其他节点最少含有 (m+1)/2 个孩子
  3. 如果根节点不是叶子结点,那么根节点最少2个孩子
  4. 所有叶子节点都在同一层,并不带任何信息
  5. 除了叶子结点,节点含有关键字属性,数目范围是 [M/2 - 1,M-1],即关键字个数 = 孩子个数 - 1。

知道了B树之后我们再来了解一下B+树,其是B树的一种变形形式,m阶B+树具有以下性质:

  1. 每个结点至多有m个孩子。
  2. 除根节点和叶结点外,每个结点至少有(m+1)/2个孩子。
  3. 如果根节点不为空,根结点至少有两个孩子。
  4. 所有叶子结点增加一个链指针且所有关键字都在叶子结点出现。
  5. 除了叶节点,结点的孩子数目等于关键字数目。 注意,B+树中非叶子结点存储的不是关键字数据的地址,而是指向叶子结点中关键字的索引。(所以任何关键字的查找必须走一条从根结点到叶子结点的路)

然后我们来对比一下B树和B+树:

首先最大的一点区别我认为就是其非叶子节点之间的区别:

B树中所有结点都存储key和data,所有结点共同组成这颗树这句话的意思就是如果你想拿到这颗树的所有data,那么你必须遍历整颗树。与之相反的是B+树中只有叶子节点才会存储data,B+树中所有叶子节点组成这棵树意思是如果你想拿到这颗树的所有data,那么你只需要遍历所有叶子节点就可以了。它们的叶子节点都不存在指针,指针只存在于非叶子节点上。另外上述B+树的第四点性质说明了B+树上所有叶子节点整体是一个链式结构,也就是每个叶子节点都有一个指向相邻叶子节点的指针,由此这样一棵树成了数据库系统实现索引的首选数据结构。

但是B树就一点好处都没有吗?显然不是这样的,因为B树中所有结点都保存了data以及磁盘预读操作(基于局部性原理),如果经常访问的数据离根节点很近,那么此时B树的数据检索效率是要比B+树高的,但是这样的操作的效率并不稳定。相比之下,B+树的优点就很多了:

  1. B+树的层级更少: 相较于B树B+每个非叶子节点并不需要存储data,由此其每个非叶子节点存储的关键字数更多,树的层级就会更少那么进行IO操作就会更少导致其查询数据更快;
  2. B+树查询速度更稳定: B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;
  3. B+树天然具备排序功能: B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。
  4. B+树全节点遍历更快: B+树遍历整棵树只需要遍历所有的叶子节点即可,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。

那么为什么MySQL为什么使用B-Tree或者是B+Tree呢?

为什么不用其他数据结构如红黑树等数据结构做索引呢?它们也可以用来实现索引呀。这里我只能简要回答了,因为涉及到了计算机组成原理相关知识,笔者也是一直半解。因为红黑树等其他平衡树都是二叉的,如果数据量非常大的情况下,其深度也是不可预估的,并且索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找索引过程中磁盘I/O操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。那么B树以及B+树因为其多路原因,其深度是远小于其他二叉平衡树的,由此MySQL使用B-Tree或者是B+Tree作为其底层索引数据结构。

聚集索引与非聚集索引

非聚集索引

MyISAM存储引擎的索引就是非聚集索引,由于索引文件和数据文件是分离的,所以每个myisam在磁盘上存储为 3 个文件数据

.frm
-------存储表结构定义
.MYD
--------MYData,存储数据
.MYI
--------MYIndex,存储索引

所以我们叫它非聚集索引,具体索引结构如下图:

image-20221026153659623

缺点就是其索引文件和数据文件是分离的,每次索引查到的是数据文件的指针地址,还需要进行额外的IO操作

聚集索引

InnoDB存储引擎的索引就是聚集索引

  • 数据文件本身就是索引文件即Innodb,只有一个文件
  • 表数据文件本身就是按B+Tree组织的一个索引结构文件
  • 聚集索引-叶节点包含了完整的数据记录

其具体索引结构如下图,

image-20221026153949721


感谢耐心看到这里的同学,觉得文章对您有帮助的话希望同学们不要吝啬您手中的赞,动动您智慧的小手,您的认可就是我创作的动力!
之后还会勤更自己的学习笔记,感兴趣的朋友点点关注哦。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值