InnoDB存储引擎底层B+树

B+树定义
B+树是为磁盘或其他存取辅助设备设计的一种平衡查找树。在B+树中,所有记录节点都是按照键值的大小顺序存放在同一层的叶子节点上,由各叶子节点指针进行连接。B+树特性:高度、页page、扇出fan out。

举例:
上图B+树中,所有记录节点都在叶子节点上,并且是顺序存放的,如果用户从左边的叶子节点开始顺序遍历,可以得到所有键值的顺序排序:5、10、15、20、25、30、50、55、60、65、75、80、85。

B+树的插入操作
B+树的插入操作,必须保证插入后叶子节点中的记录依然排序。为了保持B+树的平衡,对于新插入的键值,可能需要做大量的拆分页(split)操作。因为B+树结构主要用于磁盘,页的拆分意味着磁盘的操作,所以应该在可能的情况下尽量减少页的拆分功能。

B+树的删除操作
B+树使用填充因子(fill factor)来控制树的删除变化,50%是填充因子可设的最小值。B+树的删除操作同样必须保证删除后叶子节点的记录依然排序。当填充因子小于50%时,这时需要做Index Page的合并操作。

实例:页拆分与页合并
数据库主键使用自增id,与使用普通的无序的id相比,有什么优势吗?有人可能会以身份证号作为唯一主键,那这样会有什么问题呢?

B+树为了维护索引的有序性,每次插入或更新一条记录时,会对索引进行更新。假设之前基于身份证作为索引如下:在这里插入图片描述
现在以身份证号为例(或邮箱地hutong@sinna.com),有一个开头是3301的身份证号对应的记录插入数据库中,此时要更新索引,按照顺序,显然3301这个身份证号应该插入到第一个leaf page页的3101与3408之间。因为此时该页已经满了,而index page没有满。此时,需要进行页拆分(page split),操作如下:
(1)拆分第一个leaf page
(2)将中间的节点3408放入到Index page中
(3)小于中间节点3408的记录放左边
(4)大于等于中间节点3408的记录放在右边
操作结果如下:
在这里插入图片描述
这种由于页拆分造成的调整,必然导致性能的下降,尤其以身份证作为主键的话,由于身份正号的随机性,必然造成大量的随机节点的插入,进而造成大量的页分裂,造成性能的急剧下降。
而如果使用自增id作为主键,由于新插入的记录的id是顺序递增的,那么它可能会放到最后那个不满的leaf page中,就不会存在页的拆分问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值