数据库面试题:聚集索引,非聚集索引的底层实现

一.B(B-)树与B+树的简介

  • 在了解Mysql数据库索引的实现之前,就必须知道B树与B+树的相关知识,否则根本无法进行学习

1.1 B(B-)树

  • 首先明确一个概念:B树就是B-树
  • 如果想要详细学习B树或者B-树,那么就看这篇博客:B树详解
  • 这里仅仅对B树做一个简单的介绍
    1)B树是平衡树,类似于二叉排序树,所以左子节点的数据一定小于父节点,右子节点的数据一定大于父节点
    2)但是B树每一个节点的结构是一个线性表,分别存储关键字(key:也就是数据)和指向子节点的指针。
    3)举个例子:例如如图的【3,7】节点,实际上里面存储的是
    【point1, 3,point2, 7,point3】
    4)所以每次查询的时候从根节点开始比较关键字,如果找不到就去子节点找
    5)至于B树的插入删除这里就不介绍了,自己看上面的博客连接 在这里插入图片描述

1.2 B+树简介

  • B+树是B树的变式,两个各有千秋
  • 如果想要学习B+树的详细知识可以看这篇博客:B+树详解
  • B+树最大的区别就是所有的数据都是存储在叶子节点上的,而非叶子节点中存储的都是数据索引。并且所以的叶子结点再连城一个链表!
  • B+ 树的三个优点:
    1)层级更低,IO 次数更少,因为非叶子节点中不存储数据,只存储索引,这就导致里面可以存储更多的索引!所以IO的次数更少,整个树变变的矮胖起来
    2)每次都需要查询到叶子节点,查询性能稳定,而B树的查询性能是不稳定的,有时候可能在根节点查到,有时候可能在叶子结点查到
    3)叶子节点形成有序链表,当我们进行即品范围查询的时候,直接在这个链表中寻找范围即可,范围查找更加方便在这里插入图片描述

二. 聚集索引

2.1 聚集索引的概念

  • 我们在进行数据库建表的时候,经常会给表加上主键,没有主键的表其实在磁盘上是无序的整齐存放的,和我们所认知的‘表’的结构很相似
  • 当给表加上主键的时候,这个表就会转化成我们刚刚所说的B+树的形状,相当于整个表就变成了一个索引,所以这就成为聚集索引
  • 也就是为什么一个表只能由一个聚集索引
  • 聚集索引树中的非叶子节点只存放键值和指向子节点(数据页——叶子结点)的偏移量,叶子节点其实就是存放数据页中完整的行记录。
  • 有些博客可能会告诉我们:聚集索引按照顺序物理地址存储数据。其实不然,聚集索引的存储并不是物理上的连续,因为这样的维护成本会很高,而是逻辑上的连续!其中有两点:
    1)所有的叶子结点都是通过双向链表连接的
    2)每一个叶子结点中的行记录也是通过双向链表连接的在这里插入图片描述

2.2 聚集索引的查找

  • 每次查找的时候,都是根据主键进行查找的,也就是非叶子结点中存储的就是主键中的数据,每次查找都要找到相应的叶子结点,然后取到相应的数据
    在这里插入图片描述

2.3 比较聚集索引查询效率

  • 当我们不使用聚集索引的时候,查询的时候是一行行的查找,每次都需要进行磁盘IO,时间复杂度是O(n)
  • 当我们使用聚集索引的时候,时间直接变成了O(logn)

2.4 聚集索引带来的问题

  • 有了聚集索引,那么查询自然是快了许多,但是实际上为增,删等写入数据的操作变慢
  • 原因是因为每次写入操作都需要进行平衡二叉树的判断,修改树的结构,这样肯定是浪费了时间的!

三. 非聚集索引

3.1 非聚集索引的概念

  • 非聚集索引就是讲主键以外的字段作为索引,其实就是我们平常所使用的索引
  • 每次当我们定义一个字段为非聚集索引,那么数据库就会将这个表中的该字段复制一份构成一颗B+树,这棵B+树中的叶子结点存储的是相应的主键,非叶子结点存储当然是索引指针了
  • 如果我们定义多个字段分别为非聚集索引,那么就会生成多颗B+树,并且是不互相干扰的!

在这里插入图片描述

3.2 非聚集索引的查找

  • 非聚集索引的查找其实就是最终查找到相应的主键,然后再通过聚集索引树去查找数据——所以可以看做是二次查找
  • 也就是说无论以任何方式查找表,最终都要用主键通过聚集索引来定位数据——除了覆盖索引(下面会讲到)
    在这里插入图片描述

三.覆盖索引

3.1 覆盖索引的概念

  • 覆盖索引指的是将多个字段一起设置为索引,也就是组合索引
  • 和非聚集索引一样,同样会生成一科非聚集索引树,

3.1 覆盖索引的查找过程

  • 例如将username和userbirthday作为组合索引
  • 我们的查找目标是:userbirthday。
  • 查找的时候首先在非聚集索引树中查找该索引,找到相应的数据主键
  • 但是这时候我们就要注意了,一般情况下我们又要回到聚集索引树中去根据主键查找该用户的userbirthday,但是实际上我们的非聚集索引树中已经存储了该数据,所以可以不用做这一步了!直接取到数据
    在这里插入图片描述

四.总结

  • 这就是聚集索引,非聚集索引,覆盖索引的概念和实现了,我觉得讲的还是比较清楚的
  • 该篇博客的编写参照了这篇博主的文章:https://blog.csdn.net/itguangit/article/details/82145322
  • 希望能对大家有帮助,有帮助的话可以点个赞喔!谢谢!
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值