b+树
前言:本文将针对课程学习过程中遇到的一些难理解的地方尽量以通俗的方式着重讲解,不定期持续更新中~ ————20 ics 七海
什么是索引(Index)?
MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构
索引的目的在提高查询效率。如果没有索引就需要a-z进行全表扫描。
一般来说索引本身也很大,不可能全部储存在内存中,因此索引往往以索引文件的形式存储在磁盘上。
优点:
- 提高数据检索的效率,降低数据库的IO成本(不需要全表扫描)
- 通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗
缺点:
3. 实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占空间的
4. 虽然索引大大的提高了查询速度,同时却会降低更新表的速度,因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件
5. 每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息
6. 索引只是提高效率的一个因素,如果MySQL有大量数据的表,就需要花时间研究建立最优秀的索引,或优化查询语句,索引都是不停的根据业务场景不停修改调整的
为何用b+树索引?
索引顺序文件的缺点随着文件的增长性能下降,因为会创建许多溢出块。需要定期重组整个文件。
什么是b+树?
b+树是一种被广泛应用于数据库数据存储的一种数据结构。
(树?每个节点包含了到下一个子节点的单向指针(就像你家的住址,精确到门牌号就可以准确定位到你家,这里的指针指向的是节点所在磁盘空间的地址),一个父节点连接多个子节点形成了一个树状图)
B+树索引文件的优点:
在面对插入和删除时,通过微小的局部更改自动重新组织自己。
(次要)B+树的缺点:
额外的插入和删除开销,空间开销。B+树的优点大于缺点,所以B+树被广泛使用。
b+树的特点
“short” and “Fat” 层数少,每层的元素多
Disk-based: usually one node per block; large fanout
Balanced (more or less): good performance guarantee.
b+树节点
b+树的节点示意图如上,k是Search-key value,p是指向子节点的指针。
b+树定义!!!重点(所有插入删除操作都是依据这点来的)
n阶b+树是指一个节点中有n个可以指向子节点的指针的b+树,上图是一个三阶b+树
根节点(Root): 至少有2个子节点,也就是至少两个指针被使用(除非b+树只有一层),不满足则需重构(Merge)
非叶节点(中间节点):至少(n + 1) / 2个节点被使用(n/2向上取整),否则需要重构。
叶子节点:每个叶子节点必须包含至少(n - 1) / 2个键。叶子节点间有指针相连,形成一个链表。
b+树的插入操作
- 找到将出现搜索键值的叶节点
- 如果搜索键值已经存在于叶节点中
2.1. 向文件中添加记录
2.2. 如果需要,添加一个指向桶的指针。
直接更新bucket中的值 - 如果搜索键值不存在,则:
3.1. 将记录添加到主文件(并在必要时创建一个bucket)
3.2. 如果叶节点中有空间,则在叶节点中插入(键-值、指针)对
3.3. 否则,拆分节点(以及新的(键-值、指针)条目)。
拆分操作(split)
拆分叶节点
将原有的n-1个k和新插入的k放在一起排序,取第**[(n / 2)向上取整 + 1]**个k作为父节点中的key,第1~n/2向上取整个k放在左子节点,剩下的放在右子节点。
拆分非叶节点
先拆分完子节点后需要检查叶节点是否溢出。
将原有的n-1个k和新插入的k放在一起排序,取第**(n / 2)向上取整 个k作为父节点中的key,第1~[(n / 2)向上取整 - 1]个k放在左子节点,第[(n / 2)向上取整 + 1]**到最后的节点放在右子节点。
b+树的删除操作
找到要删除的记录,并从主文件和bucket(如果存在)中删除它
如果没有bucket或bucket已为空,则从叶节点删除(搜索键值、指针)。
如果节点由于删除而有太少的条目,并且节点和同级节点中的条目可合并成单个节点(加起来不超过n-1) ,那么合并兄弟节点。
否则,如果该节点由于删除而有太少(非叶节点少于(n + 1) / 2,叶子节点少于(n - 1) / 2)的k,但该节点及其兄弟节点中的k(加起来超过n-1)不能合并单个节点,则重新分配指针向兄弟节点借一个相邻的k过来 。
需要注意更新父节点中的索引k
节点删除可以向上级联,直到找到一个具有[n/2]或更多指针的节点。
如果根节点在删除后只有一个指针,它将被删除,唯一的子节点成为根节点。