【索引的数据结构】第1章节:B+Tree存储结构

news2024/11/27 7:45:12

目录结构

之前整篇文章太长,阅读体验不好,将其拆分为几个子篇章。

本篇章讲解 B+Tree 存储结构。

什么是索引

可以简单理解为索引好比一本书的目录,通过目录我们可以快速定位到我们要查看的章节。

MySQL 中的数据同样也是根据索引分类,通过索引可以快速高效的查询到我们想要的数据。

索引的优缺点

MySQL 官方对索引的定义:索引(Index)可以帮助 MySQL 高效获取数据的数据结构

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

InnoDB 存储引擎底层默认采用 B+Tree 作为索引的数据结构

先看下二叉搜索树的结构(一个节点存放一条数据):

可以理解为 B+Tree 是从二叉搜索树的基础上演变而来的(一个节点存放多条数据)。

建立索引的目的是为了减少磁盘的 I/O 次数,加快查询效率。

索引是在存储引擎中实现的,不同的存储引擎支持的索引类型不一定相同。

存储引擎可以定义每张表的最大索引数最大索引长度。 所有的存储引擎支持每个表至少 16 个索引,一个索引的长度为 16 个字节,所以支持的最少总索引长度为 256 个字节。

优点

  • 提高数据检索效率,降低数据库磁盘 I/O 成本
  • 通过创建唯一索引,可以保证数据库中每一行的数据的唯一性
  • 加速表和表之间的连接,对于有依赖关系的子表和主表联合查询的时候,可以提高查询速度
  • 在使用分组和排序进行数据查询时,可以显著减少查询中分组和排序的时间,大大降低了 CPU 的消耗

缺点

  • 增加索引和维护索引要耗费时间,并且随着数据量的增加,所耗费的时间会越来越大
  • 除了数据表要占用空间之外,索引也需要占用磁盘空间,并且不同的存储引擎,索引和数据的存储位置可能不同,InnoDB 存储引擎是将索引和数据存放在一个以.ibd结尾的文件中,MyISAM 存储引擎将索引和数据分开存储,索引存放在以.myi为结尾的文件中,数据存放在以.myd结尾的文件中
  • 虽然索引大大提高了查询速度,但是却会降低更新表的速度。当表中的数据要进行增删改的时候,索引也要动态维护(要重新动态分组归类排序数据的存储结构),这样就降低了数据的维护速度。

InnoDB 数据存储格式

区分记录

用户记录页目录项记录页如何区分?

使用记录头里的record_type属性,各个取值的含义如下:

  • 0:普通的用户记录
  • 1:目录项记录
  • 2:最小记录
  • 3:最大记录

假设有一张数据表 test_table有四个字段:c1、c2、c3

create table test_table (
  c1 int,
  c2 int,
  c3 char,
  PRIMARY KEY(c1)
) engine=InnoDB

由于页的编号可能不是物理连续的,只要求再逻辑上连续即可,向表中插入多条数据后,可能如下图所示:

但是挨个查找的话,数据量大的时候比较耗时。

为每个页建立一个目录项,每个目录项有一个 key(存储当前页最小的主键值)、page_no 存储页码,大致结构如下如下图所示:

行和行之间以单链表存储,页和页之间以双向链表存储。

记录与记录之间以单链表存储,叶子节点与叶子节点之间以双向链表存储。

迭代优化 1:目录项记录的页

为每个页新建一个目录项之后,考虑到后续数据量会越来越大,如果目录项在物理空间中连续存储,对于新增页或删除页时,目录项也会随之发生,这样就会消耗大量的时间,所以将目录项也简单理解为一个行记录,目录项之间也用单项列表形式存储,也就是为多个目录项建立一个页,这样新增或者删除时,直接改变指针指向即可,效率客观的很,如下图所示:

迭代优化 2:多个目录项记录的页

多个目录项记录页之间的关联如下图所示:

迭代优化 3:多个目录项记录页记录的页

多个目录项记录页组成的也目录页,如下图所示

B+Tree 结构

层层往上汇聚之后,最终形成了一个 B+Tree 的结构:

不论是存放用户记录的数据页,还是存放 目录项记录的数据页,最终都存放在 B+Tree 的结构中,所以我们撑这些数据页为节点。

实际用户记录都存放最下面的节点上,这些节点称为 叶子结点,其余用来存储 目录项的节点被称为 非叶子节点内节点,其中 B+Tree 最上边的节点也称为 根节点(可能会有多个根节点)。

一个 B+Tree 的结构可以分为很多层,规定最下面的层,也就是存放实际用户记录的那一层为第 0层,之后依次往上加。

上述的例子中我们假设存放实际记录的页 最多存 3 条记录,存放目录项记录的页 最多存放 4 条记录,其实真实的开发环境中存放的记录数非常大,假设存放实际记录的数据页(最下层的叶子节点)最多可以存放 100 条记录,存放目录项的数据页(上层的非叶子节点)最多可以存放 1000 调记录,那么计算方式如下:

  • 如果 B+Tree 有 1 层,也就是只有一个存放用户记录的节点,最多能存放 100 条记录
  • 如果 B+Tree 有 2 层,最多能存放 1000 * 100 = 10,0000条记录
  • 如果 B+Tree 有 3 层,最多能存放 1000 * 1000 * 100 = 1,0000,0000条记录
  • 如果 B+Tree 有 4 层,最多能存放 1000 * 1000 * 1000 * 100 = 1000,0000,0000条记录

到达 4 层的时候,就可以存放 1000,0000,00001000 亿条记录了,但是真实的环境中几乎不可能存到 1000 亿条,所以我们用到的 B+Tree 一般都不会超过 4 层。

假设我们是精确查找某一行数据,那在每一层通过二分法或者其他算法找到目录数据页,一次 I/O,然后再查找第二层的数据页,也是一次 I/O,所以精确查找某一行数据最多会经历四次 I/O,如果是范围查询就会有很多次 I/O 了。

本文内容总结借鉴于康师傅的 MySQL 视频课:https://www.bilibili.com/video/BV1iq4y1u7vj


在这里插入图片描述

一起学编程,让生活更随和!

如果你觉得是个同道中人,欢迎关注博主gzh:【随和的皮蛋桑】。

专注于Java基础、进阶、面试以及计算机基础知识分享🐳。偶尔认知思考、日常水文🐌。

在这里插入图片描述


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

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

相关文章

ROS TF坐标变换 - 位姿描述与消息类型

目录 一、位姿描述二、位姿相关消息体类型2.1 geometry_msgs/TransformStamped2.2 geometry_msgs/PoseStamped 在机器人系统中,有许多运动机构和传感器,为了描述他们之间的相对位姿关系,分别为他们定义了各自的坐标系,通过坐标系转…

合伙企业法关于合伙企业的要求

合伙协议可以载明合伙企业的经营期限和合伙人争议的解决方式。 合伙协议经全体合伙人签名、盖章后生效。合伙人依照合伙协议享有权利,承担责任。 经全体合伙人协商一致,可以修改或者补充合伙协议。 申请合伙企业设立登记,应当向企业登记机关提…

B2005 字符三角形(python)

a input() print( a) print( a a a) print(a a a a a)python中默认输入的是字符型,第一句就是输入了一个字符赋给a python中单引号内的也是字符串,用print输出需要连接的字符串时用加号加在后面即可

Spring通信传参的方法

Spring通信传参的方法 目录概述需求: 设计思路实现思路分析1.简单参数传递2.复合参数3.动态参数 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better resul…

爬虫基础一(持续更新)

爬虫概念: 通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程 分类: 1,通用爬虫:抓取一整张页面数据 2,聚焦爬虫:抓取页面中的局部内容 3,增量式爬虫&…

消息中间件常见知识点

一:消息队列的主要作用是什么? 1.消息队列的特性: 业务无关,一个具有普适性质的消息队列组件不需要考虑上层的业务模型,只做好消息的分发就可以了,上层业务的不同模块反而需要依赖消息队列所定义的规范进行…

JVM篇:JVM的简介

JVM简介 JVM全称为Java Virtual Machine,翻译过来就是java虚拟机,Java程序(Java二进制字节码)的运行环境 JVM的优点: Java最大的一个优点是,一次编写,到处运行。之所以能够实现这个功能就是依…

go语言语法基础

文章目录 前言一、输入和输出常用的字符串格式化符号 二、注释三、Go常用基本语言数据类型数字类型布尔类型字符类型变量与常量数组和切片数组切片 map类型创建map增删改查特别提醒 指针 四、运算符五、条件判断语句if系列switch六、循环语句for循环标准写法死循环while循环do …

java设计模式学习之【观察者模式】

文章目录 引言观察者模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用观察者示例代码地址 引言 想象你在一个在线拍卖会上竞标一件珍贵的艺术品。每当有人出价更高,系统都会立即通知你。这个实时更新机制使你可以做出快速反应。这种模式&#x…

Linux之进程管理

什么是进程 在linux中每个执行的程序都称为一个进程,每个进程都分配一个ID号(pid进程号)。每个进程都可能以两种方式存在,即前台和后天。前台进程就是用户目前的屏幕上可以进行操作的。后台进程则是实际在操作,但屏幕…

hugo-theme-kiwi V0.0.2 博客主题上新了时间轴

至此佳节,我在此给正在屏幕前浏览本文的您和您的家人,恭祝元旦快乐,虽然,这声祝福是晚了,但却不妨碍我我由内心深处对您和您的家人的诚挚祝福! 新的一年,从这一天逐渐步入我们的生活&#xff0c…

web等保评测需要实机查看的操作系统、服务器、数据库和应用部分

“等保测评”全称是信息安全等级保护测评。是经公安部认证的具有资质的测评机构,依据国家信息安全等级保护规范规定,受有关单位委托,按照有关管理规范和技术标准,对信息系统安全等级保护状况进行检测评估的活动。 本文陆续将遇到的…

『番外篇九』SwiftUI 实战:打造一款“五脏俱全”的网络图片显示 App(上)

概览 俗话说得好:“读书破万卷,下笔如有神”。不过如果把这句话放到编程的学习上可就不那么贴切了。 要想熟练掌握一门编程语言,光看书是绝对不够的。我们还需尽可能的多撸码、早撸码,撸到无路可退、海枯石烂才有可能一窥门径。 在本篇和续篇博文中,我们将和小伙伴们一起…

手把手教你绘制和解读实用R列线图(Nomogram):从入门到精通

一、引言 列线图(Nomogram)是一种常用的数据可视化工具,它能够直观地展示多个变量之间的关系,并帮助我们理解和解释复杂的数据模式。通过绘制列线图,我们可以将各种变量的影响和相互关联转化为图形化的表示&#xff0c…

2001-2021年各省高速公路里程数据

2001-2021年全国及各省高速公路里程数据 1、时间:2001-2021年 2、指标:高速公路里程 3、范围:全国及30个省市 (不含西藏) 4、来源:各省NJ、省TJGB、第三产业TJNJ (无缺失) 5、指…

鸿蒙项目方舟框架(ArkUI)之线性布局容器Stack组件

鸿蒙项目方舟框架(ArkUI)之线性布局容器Stack组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Stack组件 堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。 …

docker Mysql-udf-http

1.Mysql-udf-http镜像已上传到dockerhub中 docker pull heidaodageshiwo/mysql-udf-http:v1 2.启动镜像(默认密码root1234) docker run -tid -p 3306:3306 --namemysql-udf-http --privilegedtrue heidaodageshiwo/mysql-udf-http:v1 3.命令 [rootlocalhost ~]# docker im…

Navisworks各版本安装指南

Navisworks 下载链接 https://pan.baidu.com/s/1DGD9TbSa6Xjd-HoySd5AYg?pwd0531 1.鼠标右击【Navisworks2024(64bit)】压缩包(win11及以上系统需先点击“显示更多选项”)【解压到 Navisworks2024(64bit)】。 2.打开解压后的文件夹,双击打…

大甩卖-(CWRU)轴承故障诊数据集和代码全家桶

Python-凯斯西储大学(CWRU)轴承数据解读与分类处理 Python轴承故障诊断 (一)短时傅里叶变换STFT Python轴承故障诊断 (二)连续小波变换CWT_pyts 小波变换 故障-CSDN博客 Python轴承故障诊断 (三)经验模态分解EMD_轴承诊断 pytorch-CSDN博客 Pytorch…

大数据规模存储的几个核心问题

文章目录 三个关键问题RAID(独立磁盘冗余阵列)RAID是如何解决关于存储的三个关键问题?水平伸缩 大规模数据存储都需要解决几个核心问题,这些问题都是什么呢? 三个关键问题 1.数据存储容量的问题 既然大数据要解决的…