Mysql 学习(四)InnDB 存储引擎-B+树索引

news2024/10/5 17:15:42

没有索引的查找

  • 上节我们知道了数据是怎么存储的,数据被分成一个个页,然后页与页之间是根据双向列表来进行连接的,页中的记录是根据单向列表来进行连接的,并且将主键生成页目录。
  • 根据这个规则我们查找对应的记录数据,就有可能分成两种方式:
    • 第一种,就是不通过查找主键的记录数据时,我们只能通过遍历每个页数据,并且遍历每个页的单向链表表来查找对应的记录数据
    • 第二种,就是通过查找主键的记录数据,我们还是需要遍历每个页的数据,但是我只需要遍历每个页页目录来查找对应的记录数据
  • 毫无疑问以上的方式,对于记录少的时候问题不大,但是数据量一旦过大,就会有很大的性能问题。
  • 那这个方法怎么解决呢?
  • 这个时候就需要引出索引的概念

索引

  • 还是用上节的那一个表,记录也是上节那些,假设现在页号是8,结构如下图:
CREATE TABLE page_test ( p1 INT, p2 INT, p3 VARCHAR ( 10000 ), PRIMARY KEY ( p1 ) ) CHARSET = ascii ROW_FORMAT = Compact;

在这里插入图片描述

  • 上一节也说到,页与页之间,页号是不一定连续,也就是说当前我们的页号是8,可能下一条记录插入的时候,产生新的页,页号可能就是36,如下图
    在这里插入图片描述
  • 但是通过上图也能得知,记录与记录之间,主键一定是由小到大的关系,也就是说,下一个数据页中的数据记录的主键值一定大于上一个数据页中的数据记录主键的值。有了这个前提,我们就可以有一个大胆的想法
  • 假设我们如果把页的第一个记录的主键,当作一条记录的主键,然后页号当作值,把每个页号当作记录存到一个页里面,是不是可以大大加快主键的查询,如下图
    在这里插入图片描述
  • 然后我们的查询流程就变成,假设我们要找到主键值为5的记录:
    • 先从页号26中根据二分法找出主键值为5在页号为36的数据页中
    • 然后在从36的数据页再做一次二分法,找到主键值为5的记录数
  • 至此我们就通过两次二分查找,找到对应主键为5的记录数
  • 为了实现上面那种想法,之前 record_type 就排上用场了,通过上节知道 record_type 有 4个值,当为1的时候 就说明这个记录是索引记录,并且为了能够跟普通记录区分开,InnoDB 做了一下操作:
    • 目录项记录的record_type值是1
    • 目录项记录只有主键值和页的编号两个列
    • 只有在存储目录项记录的页中的主键值最小的目录项记录的min_rec_mask值为1,其他别的记录的min_rec_mask值都是0
  • 上面解决了怎么存放索引记录的问题,但还有一个问题,InnoDB是使用页来作为管理存储空间的基本单位,也就是最多能保证16KB的连续存储空间,而随着表中记录数量的增多,需要非常大的连续的存储空间才能把所有的目录项都放下,这对记录数量非常多的表是不现实的,所以当一个表中的数据太多,以至于数据页太多,一个数据页存放不下怎么办呢?
  • 最简单的方法是,再加一个数据页存放,但是这样又回到之前的问题,又需要遍历索引数据页,顺序查找,那现在又怎么办呢?
  • 聪明的人已经想到了,再来一层,把这些索引数据页在来一层,结构就变成下面:
    在这里插入图片描述
  • 这个结构就是传说中的树

B+ 树索引

在这里插入图片描述

  • 准确的说,InnoDB的结构是B+树,不论是存放用户记录的数据页,还是存放目录项记录的数据页,我们都把它们存放到B+树这个数据结构中了,所以我们也称这些数据页为节点。从图中可以看出来,我们的实际用户记录其实都存放在B+树的最底层的节点上,这些节点也被称为叶子节点或叶节点,其余用来存放目录项的节点称为非叶子节点或者内节点,其中B+树最上面的那个节点也称为根节点。
  • 基本上树的一般都只有4层,假设我们一个数据页的记录数是100,当树只有1层时,我们可以存放100条,当树有2层时,我们可以存放100 x 100 = 10000 记录,当树有3层时,我们可以存放 100 x 100 x 100 = 1000000 记录,当树有4层时,我们可以存放 100 x 100 x 100 x 1000 = 100000000条记录,就已经很多了。
  • 而我们根据索引去查找数据,只需要要通过4次二分查找就能找到对应的数据

聚簇索引

  • InnoDB 存储引擎会自动的为我们创建聚簇索引,也就是说聚簇索引就是InnoDB的存储方式。现在有个问题什么是聚簇索引?
  • 聚簇索引需要满足两个条件:
    • 使用记录的存放逻辑是根据主键的大小来进行排序的,具体规则:
      • 页内的记录是按照主键的大小顺序排成一个单向链表。
      • 各个存放用户记录的页也是根据页中用户记录的主键大小顺序排成一个双向链表。
      • 存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中目录项记录的主键大小顺序排成一个双向链表。
    • B+ 树的叶子节点存储的是完整的记录数据

二级索引

  • 以上索引大概思路差不多讲完了,但此时还有一个很大的问题,就是我们之前都是建立在用户只用主键进行搜索的情况下来创建,但是假设他要根据别的字段进行建立索引呢?或者说一张表会有多个索引怎么办呢?
  • 我们先来自己想想,一般情况下,怎么做,如果是我就会根据我们想要创建索引的字段,再建造一个B+树,就是说把索引字段当作主键创建一颗树,就像下面这样
    在这里插入图片描述
  • 那现在这个表就会存两个B+树,使用哪个索引就查那个表。
  • 这样虽然解决了,但是我觉得数据存两份,冗余太多了,有没有简便的方案。有没有可能 非主键 的 B+ 树,底层的叶子节点不存数据记录,只存主键,然后通过找到主键再从主键 B+ 树找到对应的数据。
  • 事实上人家InnoDB就是这么干的,而这些非主键的B+树的索引被称之为二级索引或者辅助索引

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

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

相关文章

责任链设计模式

模拟学生请假流程&#xff0c;用以说明责任链模式。 请假天数 < 10&#xff0c;老师审批&#xff1b; 10 < 请假天数 < 20&#xff0c;主任审批&#xff1b; 20 < 请假天数 < 30&#xff0c;校长审批&#xff1b; 请假天数 > 30&#xff0c;超出学校允许请假…

vulnhub Hackathon2渗透笔记

靶机下载地址&#xff1a;https://www.vulnhub.com/entry/hackathonctf-2,714/ kali ip地址&#xff1a;192.168.20.130 信息收集 扫描靶机ip地址 nmap -sP 192.168.20.0/24确定靶机ip 进行端口扫描 nmap -A -p 1-65535 192.168.20.134首先我们使用匿名用户登录ftp看看有…

Graph Transformer系列论文阅读

文章目录research1.《Do Transformers Really Perform Bad for Graph Representation》【NeurIPS 2021 Poster】2.《Relational Attention: Generalizing Transformers for Graph-Structured Tasks》【ICLR2023-spotlight】survey推荐一个汇总Graph Transformer论文的项目&…

SpringMVC事务控制(xml文件配置和注解配置)

事务的定义 事务应该具有4个属性&#xff1a;原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。 原子性&#xff08;atomicity&#xff09;。一个事务是一个不可分割的工作单位&#xff0c;事务中包括的操作要么都做&#xff0c;要么都不做。 一致性&#xff08;c…

实用的生产管理系统案例分析:如何应对市场快速变化?

生产管理系统是一种可视化管理工具&#xff0c;通过展示关键生产数据来协助企业监测生产进程。这些数据可能包括工作进度、生产速率、库存、质量、安全等。通过这些数据的可视化呈现&#xff0c;生产管理人员可以更快速地获得关于生产进程的信息&#xff0c;并能更快地做出决策…

如何将本地项目上传到Github的方法步骤

默认&#xff1a;已经安装好了git。 第一步&#xff1a;我们需要先创建一个本地的版本库&#xff08;其实也就是一个文件夹&#xff09;。 你可以直接右击新建文件夹&#xff0c;也可以右击打开Git bash命令行窗口通过命令来创建。 第二步&#xff1a;通过命令git init把这个…

深度分析MVC和MVVM:你在选择框架的时候应该注意什么?

&#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是Zeeland&#xff0c;全栈领域优质创作者。&#x1f4dd; CSDN主页&#xff1a;Zeeland&#x1f525;&#x1f4e3; 我的博客&#xff1a;Zeeland&#x1f4da; Github主页: Undertone0809 (Zeeland) (github.com)&…

SpringCloudalibaba微服务工具集

版本: Hoxton SR6 1.什么是微服务 官网 In short, the microservice architectural(架构) style is an approach to developing a single application as a suite(系列) of small services, each running in its own process(进程) and communicating with lightweight mech…

【C++基础】内联函数、nullptr(内联函数的概念;内联函数VS宏函数;内联函数的特性;C++11中的nullptr)

七、内联函数 7.1 内联函数的概念 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调用建立栈帧的开销&#xff0c;内联函数提升程序运行的效率。 应用场景&#xff1a; 短小简单的函数&#xff08;1-10行&#xff…

一篇文章把所有前端安全相关的攻击和防御都给解决了——XSS攻击和CSRF攻击

前端安全 1. XSS跨站脚本攻击 1.1 定义 XSS跨站脚本攻击(Cross Site Scripting)&#xff0c;很多人会缩写成CSS&#xff0c;但是这个缩写会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆&#xff0c;所以&#xff0c;我们通常把跨站脚本攻击缩写成XSS&#xff1b; X…

huggingface transformer模型库使用(pytorch)

参考&#xff1a; https://huggingface.co/docs transformer库 介绍 使用群体&#xff1a; 寻找使用、研究或者继承大规模的Tranformer模型的机器学习研究者和教育者想微调模型服务于他们产品的动手实践就业人员想去下载预训练模型&#xff0c;解决特定机器学习任务的工程师…

初识linux之线程控制

目录 一、POSIX线程库 二、线程创建 1.创建线程的接口 2. 错误的创建多线程 3.正确的创建多线程 4. 线程的私有栈结构 三、线程终止 1. 函数结束 2. 调用pthread_exit&#xff08;&#xff09;终止 3.调用pthread_cancel&#xff08;&#xff09;函数 四、线程等待 …

C++初阶 -1- C++入门

文章目录0.什么是C1.C关键字2.命名空间导入什么是命名空间命名空间的使用3.C 输入&输出4.缺省参数什么是缺省参数缺省参数的应用场景5.函数重载0.什么是C C是基于C语言而产生的&#xff0c;它既可以进行C语言的过程化程序设计&#xff0c;又可以进行以抽象数据类型为特点的…

基于ESP32和blinker的红外小夜灯控制

一. 系统设计及框图&#xff1a; 本设计可以实现通过手机APP使用蓝牙或WIFI远程控制红外设备&#xff0c;也可以通过离线语音模块语音控制红外设备。可以控制市面上常见的NEC格式的红外设备, 这里是控制小夜灯&#xff0c;其它红外设备在控制原理上是相通的。本设计可用作课程…

二、UVM Sequencer和Sequence

了解sequencer与driver之间传递sequence item的握手过程&#xff0c;也掌握了sequence与item之间的关系。接下来对sequence挂载到sequencer的常用方法总结&#xff0c;可以通过这些方法和宏的介绍&#xff0c;了解到它们不同的使用场景面对多个sequence如果需要同时挂到sequenc…

机器学习:基于AdaBoost算法对信用卡精准营销建立模型(附案例实战)

机器学习&#xff1a;基于AdaBoosts算法对信用卡精准营销建立模型 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&a…

OPNET Modeler 例程——M/M/1 队列建模

文章目录一、例程概述二、模型构建三、仿真配置及结果1.M/M/1 队列2.M/M/n 队列总结一、例程概述 本例程是使用节点编辑器建立一个 M/M/1 队列模型&#xff0c;同时对仿真收集到的统计数据进行数学分析。M/M/1 队列由先进先出的缓冲区组成&#xff0c;数据包的到达服从指数(泊…

Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)

目录 前言 一、动态SQL---if标签 1. 持久层添加用户通用查询方法 2. 映射文件添加相关标签 3. 测试类新建测试方法 4. 运行结果 二、动态SQL---where标签 1. 映射文件添加相关标签 2. 测试类新建测试方法 3. 运行结果 三、动态SQL---set标签 1. 持久层添加用户更新方…

DNS域名协议(IP段获取DNS服务器、反解析获取主机域名、查找子域名记录、查看子域名记录)

IP段获取DNS服务器 nmap 192.168.190.0/24 -p53 反解析获取主机域名 host 192.168.137.149 192.168.137.149 查找子域名记录 dig 192.168.137.149 -t axfr MAILMAN.com 查看子域名记录 dig 192.168.137.149 -t axfr _msdcs.MAILMAN.com

神经微分方程Resnet变体实现内存下降和保持精度

本文内容&#xff1a; 1、学习神经微分方程的笔记&#xff0c;主要锻炼自己学习新知识的能力和看有很多数学原理的论文能力&#xff1b; 2、神经微分方程可以用于时序数据建模、动力学建模等&#xff0c;但是本文专注于分类问题-resnet变体<比较容易理解>&#xff1b; …