当前位置: 首页 > news >正文

6.2.2 【MySQL】InnoDB中的索引方案

上边之所以称为一个简易的索引方案,是因为我们为了在根据主键值进行查找时使用二分法快速定位具体的目录项而假设所有目录项都可以在物理存储器上连续存储,但是这样做有几个问题:

InnoDB 是使用页来作为管理存储空间的基本单位,也就是最多能保证 16KB 的连续存储空间,而随着表中记录数量的增多,需要非常大的连续的存储空间才能把所有的目录项都放下,这对记录数量非常多的表是不现实的。

我们时常会对记录进行增删,假设我们把 页28 中的记录都删除了, 页28 也就没有存在的必要了,那意味着 目录项2 也就没有存在的必要了,这就需要把 目录项2 后的目录项都向前移动一下。

所以需要一种管理所有目录项的方式。目录项中的两个列是主键和页号,所以他们复用了之前存储用户记录的数据页来存储目录项,为了和用户记录做一下区分,我们把这些用来表示目录项的记录称为 目录项记录 。那 InnoDB 怎么区分一条记录是普通的 用户记录 还是 目录项记录 呢?别忘了记录头信息里的record_type 属性,它的各个取值代表的意思如下:

0 :普通的用户记录

1 :目录项记录

2 :最小记录

3 :最大记录

从图中可以看出来,我们新分配了一个编号为 30 的页来专门存储 目录项记录 。这里再次强调一遍 目录项记录和普通的 用户记录 的不同点:

目录项记录 的 record_type 值是1,而普通用户记录的 record_type 值是0。

目录项记录 只有主键值和页的编号两个列,而普通的用户记录的列是用户自己定义的,可能包含很多列,另外还有 InnoDB 自己添加的隐藏列。

还记得我们之前在唠叨记录头信息的时候说过一个叫 min_rec_mask 的属性么,只有在存储 目录项记录 的页中的主键值最小的 目录项记录 的 min_rec_mask 值为 1 ,其他别的记录的 min_rec_mask 值都是 0 。

除了上述几点外,这两者就没啥差别了,它们用的是一样的数据页(页面类型都是 0x45BF ,这个属性在 FileHeader 中,忘了的话可以翻到前边的文章看),页的组成结构也是一样一样的(就是我们前边介绍过的7个部分),都会为主键值生成 Page Directory (页目录),从而在按照主键值进行查找时可以使用二分法来加快查询速度。现在以查找主键为 20 的记录为例,根据某个主键值去查找记录的步骤就可以大致拆分成下边两步:

1. 先到存储 目录项记录 的页,也就是页 30 中通过二分法快速定位到对应目录项,因为 12 < 20 < 209 ,所以定位到对应的记录所在的页就是 页9 。

2. 再到存储用户记录的 页9 中根据二分法快速定位到主键值为 20 的用户记录。

虽然说 目录项记录 中只存储主键值和对应的页号,比用户记录需要的存储空间小多了,但是不论怎么说一个页只有 16KB 大小,能存放的 目录项记录 也是有限的,那如果表中的数据太多,以至于一个数据页不足以存放所有的 目录项记录 ,该咋办呢?

当然是再多整一个存储 目录项记录 的页~ 为了大家更好的理解新分配一个 目录项记录 页的过程,我们假设一个存储 目录项记录 的页最多只能存放4条 目录项记录 (请注意是假设哦,真实情况下可以存放好多条的),所以如果此时我们再向上图中插入一条主键值为 320 的用户记录的话,那就需要分配一个新的存储 目录项记录的页:

从图中可以看出,我们插入了一条主键值为 320 的用户记录之后需要两个新的数据页:

为存储该用户记录而新生成了 页31 。

因为原先存储 目录项记录 的 页30 的容量已满(我们前边假设只能存储4条 目录项记录 ),所以不得不需要一个新的 页32 来存放 页31 对应的目录项。

现在因为存储 目录项记录 的页不止一个,所以如果我们想根据主键值查找一条用户记录大致需要3个步骤,以查找主键值为 20 的记录为例:

1. 确定 目录项记录 页我们现在的存储 目录项记录 的页有两个,即 页30 和 页32 ,又因为 页30 表示的目录项的主键值的范围是[1, 320) , 页32 表示的目录项的主键值不小于 320 ,所以主键值为 20 的记录对应的目录项记录在 页30中。

2. 通过 目录项记录 页确定用户记录真实所在的页。

3. 在真实存储用户记录的页中定位到具体的记录。

如图,我们生成了一个存储更高级目录项的 页33 ,这个页中的两条记录分别代表 页30 和 页32 ,如果用户记录的主键值在 [1, 320) 之间,则到 页30 中查找更详细的 目录项记录 ,如果主键值不小于 320 的话,就到 页32中查找更详细的 目录项记录 。随着表中记录的增加,这个目录的层级会继续增加,这个就是B+树。

不论是存放用户记录的数据页,还是存放目录项记录的数据页,我们都把它们存放到 B+ 树这个数据结构中了,所以我们也称这些数据页为 节点 。从图中可以看出来,我们的实际用户记录其实都存放在B+树的最底层的节点上,这些节点也被称为 叶子节点 或 叶节点 ,其余用来存放 目录项 的节点称为 非叶子节点 或者 内节点 ,其中 B+ 树最上边的那个节点也称为 根节点 。

不论是存放用户记录的数据页,还是存放目录项记录的数据页,我们都把它们存放到 B+ 树这个数据结构中了,所以我们也称这些数据页为 节点 。从图中可以看出来,我们的实际用户记录其实都存放在B+树的最底层的节点上,这些节点也被称为 叶子节点 或 叶节点 ,其余用来存放 目录项 的节点称为 非叶子节点 或者 内节点 ,其中 B+ 树最上边的那个节点也称为 根节点 。

6.2.2.1 聚簇索引

我们上边介绍的 B+ 树本身就是一个目录,或者说本身就是一个索引。它有两个特点:

1. 使用记录主键值的大小进行记录和页的排序,这包括三个方面的含义:

页内的记录是按照主键的大小顺序排成一个单向链表。

各个存放用户记录的页也是根据页中用户记录的主键大小顺序排成一个双向链表。

存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中目录项记录的主键大小顺序排成一个双向链表。

2. B+ 树的叶子节点存储的是完整的用户记录。

所谓完整的用户记录,就是指这个记录中存储了所有列的值(包括隐藏列)。

我们把具有这两种特性的 B+ 树称为 聚簇索引 ,所有完整的用户记录都存放在这个 聚簇索引 的叶子节点处。这种 聚簇索引 并不需要我们在 MySQL 语句中显式的使用 INDEX 语句去创建(后边会介绍索引相关的语句),InnoDB 存储引擎会自动的为我们创建聚簇索引。另外有趣的一点是,在 InnoDB 存储引擎中, 聚簇索引 就是数据的存储方式(所有的用户记录都存储在了 叶子节点 ),也就是所谓的索引即数据,数据即索引。

6.2.2.2 二级索引

这个 B+ 树与上边介绍的聚簇索引有几处不同:

使用记录 c2 列的大小进行记录和页的排序,这包括三个方面的含义:

  • 页内的记录是按照 c2 列的大小顺序排成一个单向链表。
  • 各个存放用户记录的页也是根据页中记录的 c2 列大小顺序排成一个双向链表。
  • 存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中目录项记录的 c2 列大小顺序排成一个双向链表。

B+ 树的叶子节点存储的并不是完整的用户记录,而只是 c2列+主键 这两个列的值。

目录项记录中不再是 主键+页号 的搭配,而变成了 c2列+页号 的搭配。

所以如果我们现在想通过 c2 列的值查找某些记录的话就可以使用我们刚刚建好的这个 B+ 树了。以查找 c2 列的值为 4 的记录为例,查找过程如下:

1. 确定 目录项记录 页

根据 根页面 ,也就是 页44 ,可以快速定位到 目录项记录 所在的页为 页42 (因为 2 < 4 < 9 )。

2. 通过 目录项记录 页确定用户记录真实所在的页。

在 页42 中可以快速定位到实际存储用户记录的页,但是由于 c2 列并没有唯一性约束,所以 c2 列值为 4 的记录可能分布在多个数据页中,又因为 2 < 4 ≤ 4 ,所以确定实际存储用户记录的页在 页34 和 页35 中。

3. 在真实存储用户记录的页中定位到具体的记录。

到 页34 和 页35 中定位到具体的记录。

4. 但是这个 B+ 树的叶子节点中的记录只存储了 c2 和 c1 (也就是 主键 )两个列,所以我们必须再根据主键值去聚簇索引中再查找一遍完整的用户记录。

联合索引

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

  • 先把各个记录和页按照 c2 列进行排序。
  • 在记录的 c2 列相同的情况下,采用 c3 列进行排序

为 c2 和 c3 列建立的索引的示意图如下:

如图所示,我们需要注意一下几点:

  • 每条 目录项记录 都由 c2 、 c3 、 页号 这三个部分组成,各条记录先按照 c2 列的值进行排序,如果记录的 c2 列相同,则按照 c3 列的值进行排序。
  • B+ 树叶子节点处的用户记录由 c2 、 c3 和主键 c1 列组成。

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

  • 建立 联合索引 只会建立如上图一样的1棵 B+ 树。
  • 为c2和c3列分别建立索引会分别以 c2 和 c3 列的大小为排序规则建立2棵 B+ 树。

相关文章:

6.2.2 【MySQL】InnoDB中的索引方案

上边之所以称为一个简易的索引方案&#xff0c;是因为我们为了在根据主键值进行查找时使用二分法快速定位具体的目录项而假设所有目录项都可以在物理存储器上连续存储&#xff0c;但是这样做有几个问题&#xff1a; InnoDB 是使用页来作为管理存储空间的基本单位&#xff0c;也…...

划片机实现装片、对准、切割、清洗到卸片的自动化操作

划片机是一种用于切割和分离材料的设备&#xff0c;通常用于光学和医疗、IC、QFN、DFN、半导体集成电路、GPP/LED氮化镓等芯片分立器件、LED封装、光通讯器件、声表器件、MEMS等行业。划片机可以实现从装片、对准、切割、清洗到卸片的自动化操作。 以下是划片机实现这些操作的步…...

OpenCV(二十五):边缘检测(一)

目录 1.边缘检测原理 2.Sobel算子边缘检测 3.Scharr算子边缘检测 4.两种算子的生成getDerivKernels() 1.边缘检测原理 其原理是基于图像中灰度值的变化来捕捉图像中的边界和轮廓。梯度则表示了图像中像素强度变化的强弱和方向。 所以沿梯度方向找到有最大梯度值的像素&…...

上行取消指示 DCI format 2_4

上篇介绍了DCI format 2_1的DL传输中断的内容&#xff0c;这篇就看下DCI format 2_4有关的UL 传输取消机制&#xff0c;值得注意的是这里的UL传输针对的是PUSCH和SRS传输。 UL cancellation DCI format 2_4相关机制引入的背景与DCI format 2_1一样&#xff0c;都是因为URLLC和e…...

百望云蝉联2023「Cloud 100 China 」榜单 综合实力再获认可

9月7日&#xff0c;2023 Cloud 100 China 榜单于上海中心正式发布&#xff0c;榜单由靖亚资本与崔牛会联合推出&#xff0c;百望云凭借着过硬的综合实力与卓越的技术创新能力&#xff0c;再次荣登榜单&#xff0c;位居第六位。 本届评选&#xff0c;Top 100 企业的数据指标的权…...

力扣刷题班第1节:Python语法常遗漏的知识

以下仅仅记录和后面力扣刷题相关的、且平常会遗漏的语法知识。 下面这些笔记都是点到为止&#xff0c;不进行深入解释。大多数学过python的朋友看到就知道什么意思的&#xff0c;我就不解释了 字符串 str "I am a cook"# 按照空格切分 str.split(" ") …...

GET 和 POST请求的区别是什么

GET和POST是HTTP请求的两种基本方法&#xff0c;要说它们的区别&#xff0c;接触过WEB开发的人都能说出一二。 最直观的区别就是GET把参数包含在URL中&#xff0c;POST通过request body传递参数。 你轻轻松松的给出了一个“标准答案”&#xff1a; GET在浏览器回退时是无害的…...

Python数据分析实战-表连接-merge四种连接方式用法(附源码和实现效果)

实现功能 表连接-merge四种连接方式用法&#xff0c; 将两个pandas表根据一个或者多个键&#xff08;列&#xff09;值进行连接。 实现代码 import pandas as pddf1 pd.DataFrame({key: [a, b, d],data1: range(3)}) print(df1)df2 pd.DataFrame({key: [a, b, c, a, b],dat…...

NFTScan 浏览器再升级:优质数据服务新体验来袭

当前&#xff0c;高质量的 NFT 数据服务已成为区块链用户和开发者的必需。为满足用户数据需求&#xff0c;NFTScan 主站近日进行全面升级&#xff0c;优化了数据服务板块的页面结构&#xff0c;实现更清晰简洁的布局和交互。 NFTScan 的改版充分考虑用户和开发者的数据体验&am…...

C# 去除utf-8 BOM头

static void Main(string[] args) {var a1 Encoding.UTF8.GetBytes("<");var a2 Encoding.UTF8.GetBytes("&#xfeff;<");Console.WriteLine("去除utf-8 bom之前");Console.WriteLine(Encoding.UTF8.GetString(a1));Console.WriteLine(…...

Java注解以及自定义注解

Java注解以及自定义注解 要深入学习注解&#xff0c;我们就必须能定义自己的注解&#xff0c;并使用注解&#xff0c;在定义自己的注解之前&#xff0c;我们就必须要了解Java为 我们提供的元注解和相关定义注解的语法。 1、注解 1.1 注解的官方定义 注解是一种元数据形式。…...

[开学季]ChatPaper全流程教程

文章目录 1. 粗筛&#xff1a;论文全文总结1.1 使用步骤&#xff1a; 1.2 功能描述&#xff1a;2. 论文问答&#xff1a;2. 精读&#xff1a;学术版GPT的论文翻译2.0 论文精读的正确姿势2.1 使用场景1&#xff1a;arxiv论文完美翻译2.2 本地PDF全文翻译&#xff1a;2.3 关于免费…...

Spring学习笔记——4

Spring学习笔记——4 一、基于AOP的声明式事务控制1.1、Spring事务编程概述1.2、搭建测试环境1.3、基于XML声明式事务控制1.4、基于注解声明式事务控制 二、Spring整合web环境2.1、JavaWeb三大组件作用及其特点2.2、Spring整合web环境的思路及实现2.3、Spring的Web开发组件spri…...

Python数据科学入门

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 来自不同角色的人都希望保住自己的工作&#xff0c;因此他们将致力于发展自己的技能以适应当前的市场。这是一个竞争激烈的市场&#xff0c;我们看到越来越多的人对数据科学产生兴趣;该行业有数千门在线课程、训练营和…...

Ubuntu 22.04 编译 DPDK 19.11 igb_uio 和 kni 报错解决办法

由于 Ubuntu22.04 内核版本和gcc版本比较高&#xff0c;在编译dpdk时会报错。 我使用的编译命令是&#xff1a; make install Tx86_64-native-linuxapp-gcc主要有以下几个错误&#xff1a; 1.error: this statement may fall through Build kernel/linux/igb_uioCC [M] /roo…...

Android Studio.exe 下载 2023 最新更新,网盘下载

方便大家下载&#xff0c; 放到了网盘上&#xff0c;自己也保留一份。&#xff08;最前面是最新版本的&#xff0c;慎用&#xff0c; 会有bug什么的&#xff09; 个人使用4.2版本的&#xff0c;感觉够用稳定&#xff0c;其他版本有莫名奇妙的bug&#xff0c;让人头大&#xff0…...

element的el-select给下拉框添加背景

第一步 :popper-append-to-body"false" <el-selectv-model"value"placeholder"请选择":popper-append-to-body"false"><el-optionv-for"item in options":key"item.value":label"item.label&quo…...

正确理解党籍和党龄;入党和转正时间

总的来说党籍、党龄、入党时间、转正时间在性质和时间阶段上均有所区别。 党籍&#xff1a;是指党员资格。经支部党员大会讨论&#xff0c;被批准为预备党员之日起&#xff0c;就有了党籍。若被取消预备党员资格、劝退除名、自行脱党、开除党籍的&#xff0c;就失去了党籍。 …...

C语言基础:printf 函数介绍;以及常用四种常用的数据类型

printf 函数介绍 #include <stdio.h> int main() { /* * %c:字符 ; %d:带符号整数; %f: 浮点数; %s: 一串字符&#xff1b; */ int age21; printf(“hello %s,you are %d years old\n”,“Bob”,age); int i 10; double f96.20; printf(“student number%3d,score%f\n”…...

【LeetCode-中等题】209. 长度最小的子数组

文章目录 题目方法一&#xff1a;滑动窗口&#xff1a;方法二&#xff1a; 题目 方法一&#xff1a;滑动窗口&#xff1a; 参考图解动画&#xff1a;长度最小的子数组 class Solution { //方法一:滑动窗口public int minSubArrayLen(int target, int[] nums) {int n nums.l…...

比较聚合模型实战文本匹配

引言 本文我们采用比较聚合模型来实现文本匹配任务。 数据准备 数据准备包括 构建词表(Vocabulary)构建数据集(Dataset) 本次用的是LCQMC通用领域问题匹配数据集&#xff0c;它已经分好了训练、验证和测试集。 我们通过pandas来加载一下。 import pandas as pdtrain_df …...

LA@二次型@标准化相关原理和方法

文章目录 标准化方法正交变换法&#x1f388;求矩阵的特征值求各特征值对应的线性无关特征向量组正交化各个向量组 配方法步骤例例 初等变换法原理总结初等变换法的步骤例 标准化方法 正交变换法&#x1f388; 二次型可标准化定理的证明过程给出使用二次型标准化的步骤 该方法…...

Git与IDEA: 解决`dev`分支切换问题及其背后原因 为何在IDEA中无法切换到`dev`分支?全面解析!

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

什么是JavaScript中的严格模式(strict mode)?应用场景是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 严格模式&#xff08;Strict Mode&#xff09;&#xff1a;⭐ 使用场景⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…...

红外特征吸收峰特征总结(主要基团的红外特征吸收峰)

特此记录 anlog 2023年9月11日...

ChatGPT AIGC 完成关联分析散点图的应用

关联分析是数据分析中非常重要的一种技术手段,它能够帮助我们在大量数据中发现变量之间的关系和相互影响。在数据分析领域,关联分析被广泛应用于市场营销、销售预测、客户行为分析等领域。 关联分析的主要功能是通过挖掘数据中的关联规则,来发现数据集中事物之间的关联性。…...

CentOS7.6上实现Spring Boot(JAR包)开机自启

前言 Linux自启&#xff08;或开机自启&#xff09;指的是在Linux系统启动时自动运行特定的程序或脚本。当计算机启动时&#xff0c;操作系统会按照一定的顺序加载系统服务和配置&#xff0c;其中包括自动启动一些应用程序或服务。这些应用程序或服务会在系统启动后自动运行&a…...

Java开发之框架(spring、springmvc、springboot、mybatis)【面试篇 完结版】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、框架知识分布二、Spring1. spring-单例bean① 问题引入② 单例bean是线程安全的吗③ 问题总结④ 实战面试 2. spring-AOP① 问题引入② AOP记录操作日志③ …...

QT人脸识别知识

机器学习的作用&#xff1a;根据提供的图片模型通过算法生成数据模型&#xff0c;从而在其它图片中查找相关的目 标。 级联分类器&#xff1a;是用来人脸识别。 在判断之前&#xff0c;我们要先进行学习&#xff0c;生成人脸的模型以便后续识别使用。 人脸识别器&#xff1a;…...

熟悉Redis6

NoSQL数据库简介 技术发展 技术的分类 1、解决功能性的问题&#xff1a;Java、Jsp、RDBMS、Tomcat、HTML、Linux、JDBC、SVN 2、解决扩展性的问题&#xff1a;Struts、Spring、SpringMVC、Hibernate、Mybatis 3、解决性能的问题&#xff1a;NoSQL、Java线程、Hadoop、Nginx…...

网站优化的意义/好用的种子搜索引擎

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2022茶艺师&#xff08;中级&#xff09;考试练习题为茶艺师&#xff08;中级&#xff09;考题考前必练习题目&#xff01;2022年茶艺师&#xff08;中级&#xff09;考试模拟100题模拟考试平台操作依据茶艺师&#x…...

三河市最新消息/seo技术交流论坛

拿到Nuvi 350的时候&#xff0c;我惊讶不已&#xff0c;有这么小巧的GPS&#xff1f;竟然比PDA还要小一点点。把玩了一下&#xff0c;喜欢的不得了。下面我就同大家一起来分享我的Nuvi 350试用手记。 很早就去浏览台湾的Garmin网站&#xff0c;对在台湾新上市的Nuvi 350心仪不已…...

网络编程有哪些/百度搜索优化

焦红伟&#xff0c;博士&#xff0c;副教授&#xff0c;硕士生导师&#xff0c;河南省高校青年骨干教师。2015年毕业于西安电子科技大学&#xff0c;获理学博士学位。主要从事最优化算法及应用、系统优化、智能优化算法及应用等方面的研究工作。近年来对非凸规划问题的全局优化…...

常州想做个企业的网站找谁做/百度seo排名软

1 23456789查询汽车页面1011<?php 12 //造链接对象。取出用户传的值13 $db new MySQLi("localhost","root","511108","text");14 //1先定个$name "";变量15 //$name $_POST["name"];//取name的值16 $tj &…...

深圳网站建设招标/色盲测试图数字

从centos7版本开始&#xff0c;为了保持更好的开源度&#xff0c;系统最小化版本的默认数据库变为mariadb&#xff0c;但为了实验需要&#xff0c;决定还是安装mysql(毕竟两者的存储引擎是有区别的&#xff0c;尽管mariadb能很好的兼容mysql)&#xff0c;下面介绍如何安装。首先…...

java做直播网站有哪些/国外引擎搜索

HTML朋不功事做时次功好来多这开制的请一例农在 DOM增加、删除和替换节是能览调不页新代些事几求事都时学下是事点例&#xff1a;向一如分算需上来处一定迹面数一跳这件我子作div里面创建新的新直能分支调二浏页器朋代说&#xff0c;事刚需求HTML元素HTML代码遇新是直朋能到&am…...