一.B(B-)树与B+树的简介
在了解Mysql数据库索引的实现之前,就必须知道B树与B+树的相关知识,否则根本无法进行学习。
1.1 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+ 树的三个优点:
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 非聚集索引的查找
- 非聚集索引的查找其实就是最终查找到相应的主键,然后再通过聚集索引树去查找数据——所以可以看做是二次查找
- 也就是说无论以任何方式查找表,最终都要用主键通过聚集索引来定位数据——除了覆盖索引(下面会讲到)
四.覆盖索引
4.1 覆盖索引的概念
- 覆盖索引指的是将多个字段一起设置为索引,也就是组合索引
- 和非聚集索引一样,同样会生成一科非聚集索引树
4.1 覆盖索引的查找过程
- 例如将username和userbirthday作为组合索引
- 我们的查找目标是:userbirthday。
- 查找的时候首先在非聚集索引树中查找该索引,找到相应的数据主键
- 但是这时候我们就要注意了,一般情况下我们又要回到聚集索引树中去根据主键查找该用户的userbirthday,但是实际上我们的非聚集索引树中已经存储了该数据,所以可以不用做这一步了!直接取到数据
————————————————
版权声明:本文为优快云博主「我是方小磊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_44844089/article/details/105991249