MySQL BTREE索引

2022-06-05  本文已影响0人  左轮Lee

个人能力有限,如有错误请指出,共同学习。


目录:
一、二叉树、B树、B+树及其特点
二、聚簇索引和二级索引
三、索引存储数据量估算
四、索引插入过程
五、索引页面回收
六、参考文档

一、二叉树、B树、B+树及其特点

二叉树

二叉树.png
特点:

B树

B树.png
特点:

B+树

B+树.png

特点:

MySQL BTREE索引使用的就是B+树存储,下面是一个BTREE索引大致结构: B+树网络.png
二、聚簇索引和二级索引

聚簇索引

二级索引

三、索引存储数据量估算

key数据存储量估算:
若每个页可以存1000个key,而且树的高度是4,那么

四、索引插入过程

前提条件如下:

插入步骤
步骤一
因为索引中还没有数据,所以此时的B+树只有一个空的根结点,又由于一个页只能存3个key,首先将10,20,5插入进去(实际上此步发生了3次插入),然后在页面内做数据排序,最终结果如下图:

步骤1.png

步骤二:
由于根页面已经写满,此时插入8,将发生分裂(根页面分裂),大致步骤如下:
注意:在分裂过程中,根结点始终是不会变的,不管变成多大的树,根结点的页面号始终如一。

步骤五:
插入数据40,发现比根结点23大,找到103号页面,发现已满,执行分裂,分裂同上面叶子结点的分裂步骤。分裂后如图所示:

步骤5-1.png 插入40: 步骤5-2.png

步骤六:
继续插入下一个数据9,因为比20小,找到101号页面,发现已满,需要做叶子结点分裂,如下图:

步骤6-1.png 叶子节点分裂之后,需要与根结点产生父子关系,但是不幸,根结点也已满,需要做根页面的分裂。新建一个结点106,将根结点100号页面的数据复制过去,而根结点100始终是根结点,如下图所示。
步骤6-2.png 此时106号页面还是满的,key 10 还是无法写到内结点106上,需要做一次内结点分裂,新建内结点107号页面,分裂后如下图:
步骤6-3.png 分裂后105号页面就可以找到自己的爸爸了,如下图:
步骤6-4.png 此时,只是完成了分裂,数据9还没有完成插入操作,此时很明显,插入时找到页面101执行插入即可,完成后如下图所示:
步骤6-5.png 至此,所有的数据插入操作已经完成。
五、索引页面回收

传统B+树的数据删除,一般都会有一个所谓的填充因子,来控制页面数据的删除比例,如果数据量小于这个填充因子所表示的数据量,就会有节点合并,这与分裂是相对应的。
InnoDB的实现与传统B+树算法有不同之处,InnoDB在删除索引数据时,会先检查当前页剩余的记录数,如果只剩下一条记录,就会直接将这个页面从B+树中摘除,也只有这种情况,InnoDB才会回收一个页面,InnoDB的页面没有合并一说,但是对于根节点,即使索引数据全部删除,根节点页依然存在,只不过是以空页的形式存在。
下面举个例子描述索引删除过程,前提条件与前面插入记录时一致。

假设初始B+树如下(为上面插入完成后的B+树): 初始B+树

删除数据 50

删除数据50
删除数据 20 删除数据20
删除数据 10 删除数据10
删除数据 23 删除数据23
删除数据 40 删除数据40
删除数据 53 删除数据53
删除数据 8,9,21 删除8,9,21
删除数据 5 删除数据5
删除数据 22 删除数据22

删除过程全部结束,最终得到一个空的索引页。

六、参考文档

《MySQL运维内参》
B+树动画演示:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

上一篇下一篇

猜你喜欢

热点阅读