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

目录结构

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

本篇章讲解 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.hqwc.cn/news/314795.html

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

相关文章

【MATLAB】鲸鱼算法优化混合核极限学习机(WOA-HKELM)时序预测算法

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 鲸鱼算法优化混合核极限学习机(WOA-HKELM)是一种时序预测算法,它结合了鲸鱼算法和混合核极限学习机(HKELM)的优点。以下是该算法…

win10连上了wifi热点但是无法上网

我的情况是能正常连接wifi热点(手机连接这个热点能上网,说明这个wifi热点是正常的) 但是没法上网 打开cmd窗口发现能ping通百度,掘金,csdn这些网址。这就更奇怪了!于是根据上面的提示,检查了代…

【笔试强训】Day1_贪心算法_组队竞赛

题目链接:牛客_组队竞赛 目录 题目解析 代码书写 知识补充 题目解析 题目让我们求所有队伍的水平值总和最大 由题可得: 队伍的水平值等于该队伍队员中第二高水平值; 随机给定3*n个数,需要自己组队并且得出队伍水平最大值; 我…

iOS实时查看App运行日志

目录 一、设备连接 二、使用克魔助手查看日志 三、过滤我们自己App的日志 📝 摘要: 本文介绍了如何在iOS iPhone设备上实时查看输出在console控制台的日志。通过克魔助手工具,我们可以连接手机并方便地筛选我们自己App的日志。 &#x1f4…

【进阶】【Python网络爬虫】【15.爬虫框架】scrapy入门(附大量案例代码)(建议收藏)

Python网络爬虫基础 一、爬虫框架1. 什么是框架?2. 初期如何学习框架? 二、scrapy 入门1. 网络爬虫请求数据解析数据保存数据 2. scrapy安装安装方式全局命令项目命令案例 - scrapy 下厨房网爬取settings.pyspidersblood.py 案例 - scrapy爬取哔哩哔哩网…

高可用解决方案 Keepalived 概述

概述 Keepalived 介绍 Keepalived 是 Linux 下一个轻量级别的高可用解决方案,通过 **VRRP 协议(虚拟路由冗余协议)**来实现服务或者网络的高可用,可以利用其来解决单点故障。 起初是为 LVS 设计的,一个 LVS 服务会有 …

【中小型企业网络实战案例 五】配置可靠性和负载分担

【中小型企业网络实战案例 三】配置DHCP动态分配地址-CSDN博客 【中小型企业网络实战案例 四】配置OSPF动态路由协议 【中小型企业网络实战案例 二】配置网络互连互通-CSDN博客 【中小型企业网络实战案例 一】规划、需求和基本配置_大小企业网络配置实例-CSDN博客 配置VRRP联…

【Python】配置环境变量

Python配置Windows系统环境变量 打开电脑属性 ——> 高级系统设置 ——> 高级 ——> 环境变量 Python安装目录 D:\Program Files\Python39 winR打开运行,输入cmd打开命令窗口 python -V

MyBatis分页机制深度解析

前言 在企业项目的数据库操作中,分页查询是一个常见需求,尤其当数据量庞大时。MyBatis 作为 我们Java 开发者的持久层框架,为分页提供了灵活的支持。 本篇文章我们将深入探讨 MyBatis 的分页机制,使我们在实际开发项目中运用自如…

Nginx解决跨域问题过程

学习Nginx解决跨域问题 结果 server {listen 22222;server_name localhost;location / {if ($request_method OPTIONS) {add_header Access-Control-Allow-Origin http://localhost:8080;add_header Access-Control-Allow-Headers *;add_header Access-Control-Allo…

【索引的数据结构】第2章节:InooDB和MyISAM索引结构对比

目录结构 之前整篇文章太长,阅读体验不好,将其拆分为几个子篇章。 本篇章讲解 InnoDB 和 MyISAM 索引结构对比。 InnoDB 的 BTree 索引注意事项 根页面位置万年不变 上述我们在索引迭代的过程中,为了更佳形象的描述,所以将顺序…

【图像拼接】源码精读:Seam-guided local alignment and stitching for large parallax images

第一次来请先看这篇文章:【图像拼接(Image Stitching)】关于【图像拼接论文源码精读】专栏的相关说明,包含专栏内文章结构说明、源码阅读顺序、培养代码能力、如何创新等(不定期更新) 【图像拼接论文源码精…