MySQL(四):B+树索引、聚簇索引、二级索引、联合索引

news2024/11/15 3:38:52

目录

  • 一、B+树索引
    • 1.1 在没有索引时进行查找记录
    • 1.2 索引方案
    • 1.3 InnoDB中的索引方案
  • 二、聚簇索引
  • 三、二级索引
  • 四、联合索引
  • 五、InnoDB中B+树索引的注意事项
    • 5.1 根页面的位置不会改变
    • 5.2 内节点中目录项记录的唯一性
    • 5.3 一个页面至少容纳两条记录

一、B+树索引

数据库中的用来存储数据的数据页之间组成一个双向链表,并且每个数据页中的记录按照主键值从小到大的顺序组成一个单向链表,同时在每个页中都有一个页目录,在某页中查找记录时,通过二分法定位到对应的槽,遍历该槽对应分组中的记录便可找到目的记录。

1.1 在没有索引时进行查找记录

很多时候,一个表中的记录需要存储到多个数据页中,因此定位到某条记录分为两步:

  • 定位到记录所在的页
  • 在所在页中查找相应的记录

由于没有创建索引,所以需要从第一个数据页沿着双向链表查找,在每一页中通过二分法的方式定位到槽,然后再对应的分组中查找记录,由于需要遍历所有的页,这种方式是十分耗时。

1.2 索引方案

在没有索引是进行查找需要遍历所有页是因为各个页中的记录排列是没有规律的,而当建立索引后,各个页中的记录会根据索引列从小到大进行排序,同时下一页中的记录大于上一页中的记录。记录有序还不足够,还要给所有的页建立一个目录
在这里插入图片描述
通过上述索引查找某条记录也是分为两步:

  • 根据二分法在目录项中找出记录所在的页号
  • 在所在页中定位到要查找的记录

1.3 InnoDB中的索引方案

上述根据二分法在目录项中查找记录是建立在所有的目录项都存储到一个页面中的基础上,但在实际的InnoDB中,一个页大小为16KB,当表中记录非常多的时候,就无法将所有的目录项装在同一个页中。
InnoDB给出的是这样的解决方案,发现目录项和用户记录很相似,只不过目录项中的两个列分别是主键和页号,因此他们决定将目录项记录也存储到数据页中,
在这里插入图片描述

当表中的数据非常多时,就会产生很多存储目录项记录的页,为了能够根据主键快速定位到一个存储目录项记录的页,需要为存储目录项记录的页创建一个跟高级的目录,具体示意图如下
在这里插入图片描述
而上面这种组织数据的格式其实就是B+树,无论是存放用户记录的数据页还是用来存储目录项记录的数据页,都存放到B+树中,真正的用户记录只出现在叶子节点中,非叶子节点中存储的是目录项记录。

【为什么B+树的层数一般不会超过4层呢?】

我们首先假设一个页能存储100条用户记录,一个页能存储1000条目录项记录,当B+树有4层时,那么最多能存放的记录数时100010001000*100=1000亿条记录
因此在通过主键值去查找某条记录时,最多只需进行4个页面内查找(3个目录项记录的页和1个存储用户记录的页)。

二、聚簇索引

聚簇索引是指记录之间根据主键值进行排序,包括3方面含义:
(1)页内记录按照主键的大小顺序排成一个单向链表
(2)存放用户记录的页之间根据页中用户记录的主键大小顺序排成一个双向链表
(3)存放目录记录的页之间也会根据记录的主键顺序排成一个双向链表

InnoDB存储引擎会自动为我们创建聚簇索引

三、二级索引

聚簇索引只能在搜索条件是主键值时才能发挥作用,如果搜索条件中包含的并不是主键列,二级索引就是解决这个问题的,二级索引的B+树如下图:
在这里插入图片描述
二级索引与聚簇索引的不同之处:

  • 二级索引中,记录根据普通列的大小对页中记录和页之间进行排序
  • B+树的叶子节点只包含作为排序依据的列和主键列,并不是完证的用户记录
  • 目录项记录中不再是主键+页号,而变为作为排序依据的列+页号

通过二级索引查找一个记录的过程如下,假设作为排序依据的列是c1列,搜索条件是c1=10

  • 首先确定符合c1=10的目录项记录所在的页
  • 通过符合c1=10的目录项所在的页确定c1=10的用户记录所在的页
  • 在符合c1=10的用户记录中查找这条记录
  • 由于叶子节点主存储了c1列和主键列,因此还要通过该记录的主键值到聚簇索引中找出完整的用户记录(这个过程也叫做回表)

【为什么二级索引的叶子节点不存储完整的用户记录呢?】

原因很简单,太浪费空间了

四、联合索引

同时以多个列的大小作为排序规则,例如可以让B+树按照c1和c2列的大小进行排序,具体含义就是,先根据c1进行排序,在c1相同的情况下根据c2进行排序

在这里插入图片描述

五、InnoDB中B+树索引的注意事项

5.1 根页面的位置不会改变

实际生成B+树的过程如下:

  • 为某个表创建一个B+树索引的时候,都会为这个索引创建一个根节点的页面,在没有向表中插入数据的时候,根页面中也没有数据
  • 随着向表中插入数据,会先把用户记录存储到根页面中
  • 当根页面中存储不下用户记录时,再向表中插入页面时,会进行页分裂的操作,也就是产生两个新的页,将根页面中的用户记录复制到这两个新页中,根节点便升级为存储目录项记录的页

由于索引的根页面的页号是永远不会变的,因此会将这个页号存储到某个地方,后续需要用到这个索引时,就会取出根页面,对该索引进行访问

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

在前面了解到,对于二级索引来说,在目录项记录存储的是索引列+页号,但这样存储有一个问题就是,对于二级索引的索引列的值可能不是唯一的,这就可能产生一个问题,两个目录项记录的索引列值相同但页号不同,碰巧将要新插入的记录的索引列值和这两个值也相同,那么这个新插入的记录究竟要放到哪页中呢?
在这里插入图片描述
为了解决这个问题,InnoDB给出的解决方案是,在二级索引的目录项记录中,存储索引列值+主键+页号,这样就能保证除页号以外的其他目录项记录字段是唯一的在这里插入图片描述

5.3 一个页面至少容纳两条记录

为了避免B+树的层级过高,InnoDB规定所有的数据页至少可以容纳两条记录

内容参考《MySQL是怎样运行的》

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

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

相关文章

MySQL进阶篇之索引1

02、索引 2.1、索引概述 1、介绍 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向&#…

Cepstral Analysis 倒谱分析

源过滤器分离 倒谱分析是另一种将声道滤波器响应与激励分开的方法(如线性预测) 它基于以下观察:语音信号的频谱是激励频谱和声道频率响应的乘积 可以使用log将乘法转换为加法,因此,“对数频谱”可以看作是对数激励频…

十七、Gtk4-Menu and action

Menu 用户经常使用菜单向计算机发出命令。它是这样的: 现在让我们分析一下上面的菜单。对象有两种类型。 “File”, “Edit”, “View”, “Cut”, “Copy”, “Paste” and “Select All”. 它们被称为“菜单项(menu item)”或简单地称为“item”。当…

字节青训前端笔记 | 前端调试

在程序员的世界中,BUG 一词相信同学们再熟悉不过了,本节课将围绕前端开发中所遇见的 BUG 出发,讲解作为一名合格的前端开发人员,你应该掌握哪些开发调试知识 Chorme DevTools Chorme DevTools 是 chorme内核为大家提供的高效的前…

gdb使用

gdb是一款UNIX及UNIX-like下的调试工具 gdb可用于调试用gcc编译的可执行文件,用gdb调试时gcc编译需要使用参数-g 本文是对于gdb在Linux下使用的基本命令的总结gdb调试视频演示,gdb调试基础指令,gdb调试其他命令,gdb常见错误说明 目…

23种设计模式(二十一)——命令模式【行为变化】

文章目录 意图什么时候使用命令真实世界类比命令模式的实现命令模式的优缺点亦称:动作、事务、Action、Transaction、Command 意图 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递…

Centos7 Docker安装APISIX

Centos7 Docker安装APISIX1 基础介绍1.1 概念1.2 特性1.3 架构图2 快速安装2.1 前提条件2.2 安装步骤2.2.1 git命令克隆apisix-docker仓库2.2.2 docker-compose启动apisix2.2.3 访问apisix dashboard3 简单使用3.1 准备接口3.2 创建服务3.3 创建路由3.4 测试请求1 基础介绍 1.…

Kubernetes:分享一个很简洁的 k8s 管理工具 Skooner

写在前面 博文内容为 Skooner 简单介绍包括下载安装导入集群基本功能使用Skooner 的 sa 使用的当前命名空间默认的 sa不会显示创建 sa ,当然可以单独创建理解不足小伙伴帮忙指正 我所渴求的,無非是將心中脫穎語出的本性付諸生活,為何竟如此艱難呢 -----…

Spring_FrameWork_10(MyBatisPlus)

lombok mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplTestvoid selectById(){IPage page new Page(2,2);bookDao.selectPage(page,null);System.out.println("当前页码值:"page.getCurrent());System.out.println…

Java---微服务---Nacos集群搭建

Nacos集群搭建1.集群结构图2.搭建集群2.1.初始化数据库2.2.下载nacos2.3.配置Nacos2.4.启动2.5.nginx反向代理2.6.优化1.集群结构图 官方给出的Nacos集群图: 其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。 我们…

解锁Windows所有电源选项

20230123 By wdhuag 目录 参考: 查看当前选项: 警告!修改前,先使用Registry Workshop备份注册表,导出PowerSettings: 在PowerSettings里增加Attributes参数(十六进制、数值2)&a…

Shell脚本从入门到实战

Shell 文章目录Shellshell概述Shell脚本入门1. 脚本格式2. 第一个Shell脚本:helloworld3. 第二个Shell脚本:多命令处理Shell中的变量系统变量1. 常用系统变量2. 案例实操自定义变量1. 基本语法2. 变量定义规则特殊变量:$n特殊变量:$#特殊变量…

零基础学JavaWeb开发(二十二)之 springmvc入门到精通

一、SpringMVC概述 1、三层架构与MVC架构区别 1.1、三层架构 表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。 servlet层 业务逻辑层:对我们数据实现业务逻辑的封装 service层 数据访问层&#xf…

【Java|golang】2303. 计算应缴税款总额

给你一个下标从 0 开始的二维整数数组 brackets &#xff0c;其中 brackets[i] [upperi, percenti] &#xff0c;表示第 i 个税级的上限是 upperi &#xff0c;征收的税率为 percenti 。税级按上限 从低到高排序&#xff08;在满足 0 < i < brackets.length 的前提下&am…

【JavaScript】多态(Symbol),迭代器接口,getter/setter

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录多态symbol迭代器接口实现数组的迭代器方法练习Getter/Setter多态 我拿到一个对象&#xff0c;这…

【JavaScript】正则表达式详解

&#x1f4bb;【JavaScript】正则表达式&#x1f3e0;专栏&#xff1a;JavaScript &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不断提高自我的平凡人&#x1f680; &#x1f50a;分享方向&#xff1a;目前主攻前端&#…

MySQL(五):事务简介、事务的特性、事务的概念及状态、支持事务的引擎

目录一、事务的起源二、事务的特性2.1 原子性(Atomicity)2.2 隔离性(Isolation)2.3 一致性(Consistency)2.4 持久性(Durability)三、事务的概念及状态四、支持事务的引擎一、事务的起源 事务源于日常生活中的业务&#xff0c;现有这样的一个场景&#xff0c;A账户有11元&#…

人工智能学习06--pytorch04--transforms

transforms主要对图片进行一些变换 transform该如何使用&#xff08;python&#xff09; 从transform中选择一个class&#xff0c;进行创建 依据创建的工具看需要什么&#xff08;如img&#xff09; 为什么需要tensor的数据类型 tensor数据类型&#xff1a;包装了神经网络…

opencv win10 4.7.0 源码编译 vs2019 cmake

下载opencv & opencv-contrib 4.7.0源码&#xff1b;注意下载地址https://github.com/opencv/opencv/releases https://github.com/opencv/opencv_contrib/releases/tag/4.7.0 版本要一模一样cmake输出文件夹为&#xff1a;opencv-4.7.0-build 遇到下载问题如下&#xf…

常见递归模式

常见递归模式递归模式遍历二叉树模式回溯模式子问题分解模式递归模式 常见递归模式&#xff1a; 遍历二叉树模式回溯模式子问题分解模式 遍历二叉树模式 只要涉及递归的问题&#xff0c;都是树的问题&#xff0c;或者说树的遍历。 void traverse(TreeNode root) { // 遍历…