文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MySQL索引的数据结构

2023-08-31 13:25

关注

文章目录

1、索引的概念

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
在这里插入图片描述
在这里插入图片描述

索引的本质:索引是数据结构。你可以简单理解为“排好序的快速查找数据结构”,满足特定查找算法。这些数据结构以某种方式指向数据, 这样就可以在这些数据结构的基础上实现 高级查找算法

2、索引的优点

3、索引的缺点

索引是个好东西,可不能乱建,它在空间和时间上都会有消耗:

1、空间上的代价

每建立一个索引都要为它建立一棵B+树,每一棵B+树的每一个节点都是一个数据页,一个页默认会占用 16KB 的存储空间,一棵很大的B+树由许多数据页组成,那就是很大的一片存储空间。
时间上的代价

2、时间上的代价

每次对表中的数据进行 增、删、改 操作时,都需要去修改各个B+树索引。而且我们讲过,B+树每层节点都是按照索引列的值 从小到大的顺序排序 而组成了 双向链表 。不论是叶子节点中的记录,还是内节点中的记录(也就是不论是用户记录还是目录项记录)都是按照索引列的值从小到大的顺序而形成了一个单向链表。而增、删、改操作可能会对节点和记录的排序造成破坏,所以存储引擎需要额外的时间进行一些 记录移位 , 页面分裂 、 页面回收 等操作来维护好节点和记录的排序。如果我们建了许多索引,每个索引对应的B+树都要进行相关的维护操作,会给性能拖后腿。

1、设计索引

可以联想操作系统中的页表机制,一层套一层(通过目录项找页,当目录项中过多时,我们会继续设置目录项去找目录项…),最后形成B+树的形式

1)以c1创建索引(因为c1是主键)

mysql> CREATE TABLE index_demo( ->   c1 INT, ->   c2 INT, ->   c3 CHAR(1), ->   PRIMARY KEY(c1) -> ) ROW_FORMAT = Compact;

2)数据库中一条记录的格式

在这里插入图片描述

3)将记录放在数据页中

数据库中的数据在磁盘中是以数据页的形式进行存储的,每一页中的每一行叫做记录

页内的数据是按照主键值进行排序的,所以页内数据我们是可以通过二分法去查找的。
在这里插入图片描述

4)当页过多时,需要为页设置目录项

在这里插入图片描述

5)当目录项过多时,我们需要为目录项设置目录项

在这里插入图片描述

6)最后形成B+树的形式

在这里插入图片描述

一个B+树的节点其实可以分成好多层,规定最下边的那层,也就是存放我们用户记录的那层为第 0层,之后依次往上加。之前我们做了一个非常极端的假设:存放用户记录的页最多存放3条记录 ,存放目录项记录的页 最多存放4条记录 。其实真实环境中一个页存放的记录数量是非常大的(MySQL中一页的大小为16KB),假设所有存放用户记录的叶子节点代表的数据页可以存放100条用户记录,所有存放目录项记录的内节点代表的数据页可以存放1000条目录项记录 ,那么:

因此,面试中问,为什么MySQL的B+树最多只有四层?
因为四层就已经能够存储相当量的数据了,足够我们使用,毕竟四层可以存储100000000000 条记录了。

那怎么去查找我们所需要的的记录了?
通过主键值去查找某条记录最多只需要做4个页面内的查找(查找3个目录项页和一个用户记录页),又因为在每个页面内有所谓的 Page Directory(页目录),所以在页面内也可以通过 二分法 实现快速定位记录

2、常见索引概念

2.1、聚簇索引

特点

上面举的例子是基于主键进行排序的,所以是聚簇索引!

优点

缺点

2.2、二级索引(又叫辅助索引、非聚簇索引)

二级索引我们并不是将主键作为索引,而是用非主键进行索引。每一行的记录包括非主键的索引和主键。
在这里插入图片描述
因此我们利用二级索引去查找某个完整的记录,需要两步操作,第一步,通过二级索引去查找主键,第二步,通过聚簇索引去查找记录。
这就是回表操作,所以查找一条记录我们需要查找两棵B+索引树!

面试问题,为什么需要一次回表操作了?直接把完整的用户记录放到叶子节点不OK吗?
因为在数据库中不会只设置一个二级索引,如果每个二级索引的叶子结点都放置完整的用户数据(每个用户的数据可能有几百万个),会极大的加大存储空间的开销

在这里插入图片描述

2.3、联合索引

我们也可以同时以多个列的大小作为排序规则,也就是同时为多个列建立索引,比方说我们想让B+树按照 c2和c3列 的大小进行排序,这个包含两层含义:

注意一点,以c2和c3列的大小为排序规则建立的B+树称为 联合索引 本质上也是一个二级索引。它的意思与分别为c2和c3列分别建立索引的表述是不同的,不同点如下:

1、全表遍历

复杂度是O(n)的,效率很差

2、Hash结构

Hash结构的效率是很高的,时间复杂度可以为O(1)

那为什么Hash结构的效率这么搞,那为什么索引的数据结构设计成树形了?有四点原因

在这里插入图片描述

Hash索引适用存储引擎如表所示:

在这里插入图片描述

虽然在InnoDB存储引擎中,不支持Hash索引,但是却提供了自适应Hash索引(Adaptive Hash Index)。

那什么情况下使用自适应Hash索引了?

如果某个数据经常被访问,当满足一定条件的时候,就会将这个数据页的地址存放到hash表中,这样在下次查询的时候,就可以找到这个页面所在的位置。这样B+树也具备了Hash索引的优点。

在这里插入图片描述
采用自适应 Hash 索引目的是方便根据 SQL 的查询条件加速定位到叶子节点,特别是当 B+ 树比较深的时候,通过自适应 Hash 索引可以明显提高数据的检索效率。

我们可以通过innodb_adaptive_hash_index变量来查看是否开启了自适应 Hash,比如:

show variables like '%adaptive_hash_index';

在这里插入图片描述

3、二插搜索树

二插搜索树在某种情况下,时间复杂度会变成O(n)
在这里插入图片描述
为了提高查询效率,就需要 减少磁盘IO数 。为了减少磁盘IO的次数,就需要尽量 降低树的高度 ,需要把原来“瘦高”的树结构变的“矮胖”,树的每层的分叉越多越好。

4、AVL树

在这里插入图片描述

5、 B树

在这里插入图片描述
一个 M 阶的 B 树(M>2)有以下的特性:

(1)根节点的儿子数的范围是 [2,M]。
(2)每个中间节点包含 k-1 个关键字和 k 个孩子,孩子的数量 = 关键字的数量 +1,k 的取值范围为[ceil(M/2), M]。
(3)叶子节点包括 k-1 个关键字(叶子节点没有孩子),k 的取值范围为 [ceil(M/2), M]。
(4)假设中间节点节点的关键字为:Key[1], Key[2], …, Key[k-1],且关键字按照升序排序,即 Key[i]
…,P[k],其中 P[1] 指向关键字小于 Key[1] 的子树,P[i] 指向关键字属于 (Key[i-1], Key[i]) 的子树,P[k]>指向关键字大于 Key[k-1] 的子树。
(4)所有叶子节点位于同一层。

上面那张图所表示的 B 树就是一棵 3 阶的 B 树。我们可以看下磁盘块 2,里面的关键字为(8,12),它有 3 个孩子 (3,5),(9,10) 和 (13,15),你能看到 (3,5) 小于 8,(9,10) 在 8 和 12 之间,而 (13,15)大于 12,刚好符合刚才我们给出的特征。

然后我们来看下如何用 B 树进行查找。假设我们想要 查找的关键字是 9 ,那么步骤可以分为以下几步

你能看出来在 B 树的搜索过程中,我们比较的次数并不少,但如果把数据读取出来然后在内存中进行比较,这个时间就是可以忽略不计的。而读取磁盘块本身需要进行 I/O 操作,消耗的时间比在内存中进行比较所需要的时间要多,是数据查找用时的重要因素。 B 树相比于平衡二叉树来说磁盘 I/O 操作要少,在数据查询中比平衡二叉树效率要高。所以 只要树的高度足够低,IO次数足够少,就可以提高查询性能

6、B+树

B+树和B树的差异

B+树就比B树好吗?

B 树和 B+ 树都可以作为索引的数据结构,在 MySQL 中采用的是 B+ 树。但B树和B+树各有自己的应用场景,不能说B+树完全比B树好,反之亦然。

3 、思考题:为了减少IO,索引树会一次性加载吗?

不会,因为索引会占用空间,大量的索引可能会超出1g多的大小,所以不会一次性加载

思考题:B+树的存储能力如何?为何说一般查找行记录,最多只需1~3次磁盘IO

储存能力很强,倘若一开始的根页可以存放100条数据条目,那如果页目录可以存放1000条,那二级存放的量就1001000,三级就是10010001000,4级就是100100010001000,那为什么最多只需要加载最大3次呢,因为根页的数据在一开始已经加载了所有无需加载,那么就算最大加载4级,那也就需要加载最大3次

思考题:为什么说B+树比B-树更适合实际应用中操作系统的文件索引和数据库索引?

因为B+树查询更为稳定,且适合范围的快速查找

思考题:Hash 索引与 B+ 树索引的区别

HASH索引的范围查找效率比B+树索引效率低很多,且不支持联合索引

思考题:Hash 索引与 B+ 树索引是在建索引的时候手动指定的吗?

不是的,是一开始我们创建表的时候,每次插入数据,他背后都会去维护对应索引,如果又新加的二级索引才会再创建索引

7、R树

R-Tree在MySQL很少使用,仅支持 geometry数据类型 ,支持该类型的存储引擎只有myisam、bdb、innodb、ndb、archive几种。

举个R树在现实领域中能够解决的例子:查找20英里以内所有的餐厅。如果没有R树你会怎么解决?一般情况下我们会把餐厅的坐标(x,y)分为两个字段存放在数据库中,一个字段记录经度,另一个字段记录纬度。这样的话我们就需要遍历所有的餐厅获取其位置信息,然后计算是否满足要求。如果一个地区有100家餐厅的话,我们就要进行100次位置计算操作了,如果应用到谷歌、百度地图这种超大数据库中,这种方法便必定不可行了。R树就很好的解决了这种高维空间搜索问题。它把B树的思想很好的扩展到了多维空间,采用了B树分割空间的思想,并在添加、删除操作时采用合并、分解结点的方法,保证树的平衡性。因此,R树就是一棵用来存储高维数据的平衡树 。相对于B-Tree,R-Tree的优势在于范围查找

在这里插入图片描述

1、适用场景

2、不适用场景

来源地址:https://blog.csdn.net/qq_38327769/article/details/124244178

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯