mysql的B+树索引

这篇文章是自己学习mysql随手写的杂记,编辑混乱且不够严谨,请勿参考,谢谢!

以mysql中的innodb引擎为例,索引是个什么东西?为什么说索引即数据?一个2层B+树索引最多可以存多少条数据?聚簇索引,二级索引,联合索引?

在单个页中进行记录查找分为:

  • 定位记录所在的槽
  • 遍历槽比对记录

真实的场景中,表中的数据会分布在很多的页中。记录的查找也在这些页中进行,如果我们不进行任何查找优化,最简单粗暴的办法就是遍历这些所有页中,显然效率低下。可以参考一个页中进行记录查找的思路,mysql规定:

  • 一个页中的记录主键值大于上一个页中的主键值,如果一个页中的空间不够新记录存储,则会产生一个新页用以存储新记录,新页也符合此规则,这就是"页分裂"

于是,把每个页中的页号、最小记录的主键值提取出来放在目录项页中,目录项页中的数据存储主键+页号。这些记录的记录类型值为1,表明是目录项记录,且页中最小记录的min_rec_mask为1,表示是B+树非叶子节点最小记录。这些页中的数据其实就是索引。mysql自动会为表创建聚簇索引,其特点如下:

主键有序性

  • 页之间按记录主键大小从小到大形成双链表。
  • 页中记录按主键从小到大形成单链表。
  • 目录项同一层中,按照主键从小到大形成双链表。

聚簇索引的叶子节点存储的是完整的用户记录,其非叶子节点(内节点)存储的是目录项记录,忘记说明一点:一个页会对应一个目录项(主键值+页号)。每个页或目录项页都是一个节点。

如果目录项页太多则继续向上抽象出新的页以存储这些存储目录项页的信息。在记录查找时,则是:

  • 定位记录所在的页(记录多时会先定位目录项页)。
  • 再在页中定位记录。

B+树页有一个根节点,这个根节点的页号是自B+树产生时就固定不变的,其存储在某个地方,当需要查找数据时则会找到这个根节点页号,后续再进行查找。

到这里说的都是聚簇索引,目录项页存储的数据是主键+页号。那么对于一个非主键列的精确查找,如col=zhangsan。

col为普通的列,并非主键列,则目录项中存储的数据为col+主键+页号,此为二级索引。咦?为什么多一个主键值?原因是如果列值一样的,这个时候就需要按主键大小要做区分了,不然innodb无法区分哪个在前,哪个在后。在查找用户的记录时,根据列值在列对应B+树索引中只能找到目标记录的主键,这个时候还要去聚簇索引中的叶子节点取出具体的用户记录,这种查找记录的形式为回表。

通常情况下,一颗B+树不会超过4层。我们看看一棵2层的B+树可以存储多少条记录:

假设一个页中可以存储1000条数据,一个目录项页可以存储1000条目录项记录,则总的记录条数为:1000x1000=1000000,一百万的数据量,三层就上亿了,能够存储的数据量非常之大。

联合索引是把多个列联合起来做成索引,如col1,col2,则是先按col1排序,如果col1相同则按col2排序,一个联合索引就是一棵B+树,不同于对这些列建立的索引。

完。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值