更新数据时,MySQL的聚簇索引是如何变化的?

本文详细介绍了B+树在数据库索引中的应用,特别是InnoDB存储引擎下的聚簇索引原理。从根索引页开始,通过二分查找逐层定位到数据页,说明了数据查找过程。聚簇索引按照主键组织数据,增删改操作直接影响数据页,并自动维护B+树结构。讨论了页分裂、数据页指针连接以及索引层级管理,揭示了数据库高效检索的秘密。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章已收录在我的 GitHub 仓库,欢迎Star/fork:
Java-Interview-Tutorial
听说点赞、评论、收藏的人长得都很好看哦。

搜索一个主键id对应的行,先去顶层的索引页88里通过二分查找,定位到你应该去下层哪个索引页里继续找。

若现在定位到下层的索引页35,此时在索引页35里也有一些索引条目,分别都是下层各索引页(20、28、59)及他们里面最小的主键值,此时在索引页35的索引条目里继续二分查找,容易定位到,应该再到下层的索引页里找。

可能从索引页35接着就找到下层的索引页59,此时索引页59里也有索引条目,存放部分数据页页号(如数据页2、8)和每个数据页里最小的主键值。在此继续二分查找,就能定位到应该到哪个数据页里去找。

比如进入数据页2,里面就有个页目录,存放各行数据的主键值和行的实际物理位置。在此继续二分查找,即可快速定位到待搜索主键值对应行的物理位置,然后直接在数据页2里找到那条数据。这就是基于索引去查找主键的过程。

最下层的索引页,都有指针引用数据页,所以索引页之间跟数据页之间有指针连接。索引页内部,同一层级的索引页互相之间也是基于指针组成双向链表:

假设你把索引页和数据页综合起来看,他们都是连接在一起的,从根索引页88开始,一直到所有的数据页,组成了B+树。最底层的一层就是数据页,数据页也就是B+树里的叶节点。

所以,如果B+树索引数据结构里,叶节点就是数据页自己本身,即为聚簇索引!即上图中所有的索引页+数据页组成的B+树就是聚簇索引!

InnoDB下,对数据增删改时,就是直接把你的数据页放在聚簇索引,数据就在聚簇索引里,聚簇索引就包含了数据。比如你插入数据,那就是在数据页里插入数据。

若你的数据页开始进行页分裂,他此时会调整各数据页内部的行数据,保证数据页内的主键值都有序,:

下一个数据页的所有主键值>上一个数据页的所有主键值

页分裂时,也会维护你的上层索引数据结构,在上层索引页里维护你的索引条目,不同的数据页和最小主键值。

然后若你的数据页越来越多,一个索引页放不下了,就会再拉出新的索引页,同时再搞一个上层的索引页,上层索引页里存放的索引条目就是下层索引页页号和最下主键值。

同理可得,若你的数据量越大,此时可能就多出更多索引页层级,不过一般索引页里可以放很多索引条目,即使你是亿级大表,基本上大表里建的索引的层级也就三四层。

聚簇索引默认按主键组织的,所以你在增删改数据时:

  • 会更新数据页
  • 会给你自动维护B+树结构的聚簇索引,给新增和更新索引页,这个聚簇索引是默认就会给你建立
### 索引概念及特点 在 MySQL 的 InnoDB 存储引擎中,索引是一种特殊的索引形式,在这种结构下,表中的数据行被物理地存储在一起[^1]。具体而言,索引的叶节点包含了完整的行记录,这意味着当访问基于索引数据可以直接获取所需的信息而无需额外查找其他位置。 #### 特点: - 表内仅能存在一个索引; - 插入新行或更新现有行的位置取决于其键值顺序; - 对于范围查询特别有效率,因为连续的相关行会更可能位于相邻页面上; ```sql CREATE TABLE example ( id INT NOT NULL, name VARCHAR(50), PRIMARY KEY (id) -- 这里定义了一个索引 ); ``` ### 索引 vs 非索引索引(Secondary Index),又被称为辅助索引,它并不影响实际数据行的排列方式。相反,它的叶节点保存着指向对应索引条目的指针——通常是主键 ID 或者唯一标识符[^2]。因此,使用非索引来检索数据往往涉及两次I/O操作:先定位到非索引找到相应的主键ID,再利用该ID去读取真正的数据行,这一过程即所谓的“回表”。 | 属性 | 索引 | 非索引 | |-------------|----------------------------------|-----------------------------------| | 数据分布 | 按照索引键有序存储 | 不改变原始数据布局 | | 查询效率 | 更高效尤其针对单个/少量记录 | 可能较慢特别是需要频繁回表的情况 | | 更新成本 | 较高因需维护形结构 | 相对较低 | ### 回表是什么 所谓“回表”,是指通过非索引首次查得的结果只是得到了目标记录所在的具体位置信息(如主键值)。为了获得全部字段的内容,则还需要再次回到索引处进行第二次精确匹配并取出完整的一行或多行数据[^3]。这增加了磁盘IO次数从而降低了整体性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值