【Mysql】InnoDB 中 B+ 树索引的注意事项

一、根页面万年不动

在之前的文章里,为了方便理解,都是先画存储用户记录的叶子节点,然后再画出存储目录项记录的内节点。

但实际上 B+ 树的行成过程是这样的:

  • 每当为某个表创建一个 B+ 树索引,都会为这个索引创建一个根节点页面。最开始表里没数据,所以根节点中既没有用户记录,也没有目录项记录。

  • 当往表里插入用户记录时,先把用户记录存储到这个根节点上。

  • 当根节点页空间用完,继续插入记录,此时会将根节点中所有记录复制到一个新页(比如页 a),然后对这个新页进行页分裂,得到另一个新页(页 b)。这时候新插入的记录就根据键值大小分配到页 a 和 页 b 中。于是,根节点页就升级成了存储目录项记录的页,就需要把页a 和 页b 对应的目录项记录插入到根节点中。

另外,当一个B+树索引的根节点创建后,它的页号就不会再变

所以只要我们对某个表建立一个索引,那么它的根节点的页号就会被记录到某个地方,后续只要 innodb引擎需要用这个索引,就会从那个固定的地方取出根节点的页号,从而访问这个索引。

二、内节点中目录项记录的唯一性

在B+树索引的内节点中,目录项记录的内容是索引列+页号。但是对于二级索引来说,不太严谨。

因为二级索引的索引列可能存在相同的值,比如某张表里有这4条记录,其中c1列是主键 :

现在为c2列建立索引:

如果这时候继续插入一条记录,3个列分别为9、1、'c',就会遇到问题:

  • 新记录中 c2的值也是1,那么这个新记录到底应该放在页 4,还是放到页 5?

所以,为了能让新插入的记录可以找到自己应该到哪个页中,就需要保证B+树同一层内节点的目录项记录是唯一的

那么,实际上二级索引的内节点的目录项记录应该由 3 个部分组成:

  • 索引列的值
  • 主键值
  • 页号

所以实际上给c2建立的索引应该是这样:

现在,当插入新记录9、1、'c'时:

  • 可以先把新记录的 c2 列的值和页 3 中各目录项记录的 c2 列的值进行比较。
  • 如果 c2 列的值相同,就接着比较主键值。

所以,对于二级索引来说,给 c2 列建索引,其实就相当于用c2、c1建立了一个联合索引。先按照二级索引的值进行排序,在二级索引列值相同的情况下,再按照主键值进行排序。

三、一个页面至少容纳 2 条记录

在之前的文章里提到过,B+ 树其实只需要很少的层级就可以轻松存储数亿条记录,查询速度还很快。

这是因为 B+ 树本质上就是一个大的多层级目录。每经过一个目录时都会过滤许多无效的子目录,直到最后访问到存储真正数据的目录。

那么现在不妨设想一下:还是同样的数据量,如果一个大的目录只存放一个子目录,又是什么样子?

  • 目录层级非常多
  • 最后那个存放真正数据的目录中只能存放一条记录

如果是这样的话,这种B+ 树结构就没什么意义了,不能形成一个有效的索引。于是,设计 innoDB的大佬为了避免 B+树的层级增长得过高,要求所有数据页都至少可以存放2条记录

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

循环队列的实现

文章目录 循环队列的概念循环队列的实现循环队列的判空和判满链表or数组 循环队列的概念 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓…

快速下载Huggingface的大语言模型

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Huggingface是什么?二、基于官方huggingface-cli下载(基础,断线风险)1.安装hf下载环境2.配置环境变量3.注册…

CSAPP-信息的表示和处理

文章目录 概念扫盲思想理解经典好图安全事件 概念扫盲 1.大端高位在前,小端低位在前 2.逻辑运算符(&& 、||、!)与位级运算(&、|、~)的差异 3.宏可以保证无论代码如何编译,都能生成…

flutterandroidx支持,【工作经验分享】

基于Linux的pc启动过程 我们都知道,所有的程序软件包括操作系统都是运行在内存中的,然而我们的操作系统一般是存放在硬盘上的,当我们按下开机键的时候,此时内存中什么程序也没有,因此需要借助某种方式,将操…

百度SEO工具,自动更新网站的工具

在网站SEO的过程中,不断更新网站内容是提升排名和吸引流量的关键之一。而对于大多数网站管理员来说,频繁手动更新文章并进行SEO优化可能会是一项繁琐且耗时的任务。针对这一问题,百度自动更新文章SEO工具应运而生,它能够帮助网站管…

chartjs 饼状图

之前要把canvas先清除掉&#xff0c;不然刷新数据&#xff0c;还会有前面的图表 function clearCanvas(){$(#donutChart).remove();$(#chartdiv).append(<canvas id"donutChart" style"min-height: 500px; height: 500px; max-height: 500px; max-width: 70%…

浅谈mysql mvcc

目录 前言 mvcc 是如何工作的&#xff1f; 数据的更新 前言 mvcc 与一个事物的隔离级别有关&#xff0c;未提交读永远读的是当前值&#xff0c;串行化是通过加锁实现&#xff0c;这两种隔离级别都与mvcc 没有任何关系。只要一提到mvcc应该想到的是读提交以及可重复读&#…

vue+element ui上传图片到七牛云服务器

本来打算做一个全部都是前端完成的资源上传到七牛云的demo&#xff0c;但是需要获取token&#xff0c;经历了九九八十一难&#xff0c;最终还是选择放弃&#xff0c;token从后端获取&#xff08;springboot&#xff09;。如果你们有前端直接能解决的麻烦记得私我哦&#xff01;…

『Linux从入门到精通』第 ㉒ 期 - 动静态库

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f427;什么是库&#xff1f;&#x1f427;为什么要有库&#xff1f;&#x1f427;写一个自己的库&#x1f426;方法一&#x1f426;方法二 静态库&#x1f426;标准化&#x1f426;方法三 动态库&#x1f426;配置动…

python中自定义报错

class MyError(Exception):def __init__(self,num):#录入的数Exception.__init__(self)self.numnumdef __str__(self):return 这是我定义的第%d个异常 %(self.num)使用 try:raise MyError(4) except MyError as e:print(e)raise 其作用是指定抛出的异常名称&#xff0c;以及异常…

数据结构题目①——数组

前言 本篇文章为博主进行代码随想录——数组练习后的总结会涉及到每一道题目的详细的思路整理&#xff0c;以及本人的易错点&#xff0c;希望对大家有所帮助 数组介绍&#xff1a; 数组在C语言中就已经有所涉及&#xff0c;它是一个最基础的数据结构&#xff0c;而在数据结构中…

three 层级模型

group.remove(mesh1,mesh2);Vector3与模型位置、缩放属性 Group层级模型(树结构) 创建了两个网格模型mesh1、mesh2&#xff0c;通过THREE.Group类创建一个组对象group,然后通过add方法把网格模型mesh1、mesh2作为设置为组对象group的子对象&#xff0c;然后在通过执行scene.a…

jenkins部署maven项目

流程&#xff1a; jenkins从代码仓库读取代码&#xff0c;将代码文件放入jenkins的工作空间&#xff0c;将jenkins工作空间的代码进行打包&#xff0c;将jar包远程发送给服务器。 一&#xff1a;所需插件二&#xff1a;Tools 三&#xff1a;System&#xff1a; 配置ssh连接的…

python63-Python的循环之循环使用else

Python的循环都可以定义else代码块&#xff0c;当循环条件为False 时&#xff0c;程序会执行else代码块。如下代码示范了为while循环定义else代码块。 # !/usr/bin/env python# -*- coding: utf-8 -*-# Time : 2024/01# Author : Laopicount_i 0while count_i < 5:print(c…

Java集合相关面试题(2024大厂高频面试题系列)

1、说一说Java提供的常见集合&#xff1f;&#xff08;画一下集合结构图&#xff09; 在java中提供了量大类的集合框架&#xff0c;主要分为两类&#xff1a; 第一个是Collection 属于单列集合&#xff0c;第二个是Map 属于双列集合 在Collection中有两个子接口List和Set。…

【力扣hot100】刷题笔记Day14

前言 又是新的一周&#xff0c;快乐的周一&#xff0c;快乐地刷题&#xff0c;今天把链表搞完再干活&#xff01; 114. 二叉树展开为链表 - 力扣&#xff08;LeetCode&#xff09; 前序遍历 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

【IC前端虚拟项目】inst_buffer子模块DS与RTL编码

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 需要说明一下的是,在我所提供的文档体系里,并没有模块的DS文档哈,因为实际项目里我也不怎么写DS毕竟不是每个公司都和HISI一样对文档要求这么严格的。不过作为一个培训的虚拟项目,还是建议在时间充裕…

Docker技术概论(3):Docker 中的基本概念

Docker技术概论&#xff08;3&#xff09; Docker 中的基本概念 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://…

基于java+springboot女士电商平台系统源码+文档设计

基于javaspringboot女士电商平台系统源码文档设计 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…

C语言----动态内存管理(2)

1.这里总结动态内存管理里面的错误 &#xff08;1&#xff09;使用malloc开辟空间以后直接赋值 这个就是malloc开辟失败返回空指针&#xff0c;直接给空指针赋值就是错误的&#xff0c; tip1:使用malloc开辟空间以后一定要判断是否为空 &#xff08;2&#xff09; 越界访问…