MySQL数据存储、索引记录

行格式(每行记录)

行格式(每行记录):

  • 以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式。 InnoDB 存储引擎4种不同类型的 行格式 ,分别是 Compact 、 Redundant 、Dynamic 和 Compressed 行格式。
  • 组成: 记录的额外信息 和 记录的真实数据.
  • 记录的真实数据:为每条记录都添加 transaction_idroll_pointer 这两个列,但是 row_id 是可选的(没有自定义主机、Unique列时)
  • 记录的额外信息: 变长字段长度列表NULL值列表记录头信息
    • 把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占 用的字节数按照列的顺序逆序存放。
    • Compact 行格式把这些值为 NULL 的列统一管理起来,存储到 NULL 值列表中
    • 记录头信息:
      • delete_mask 被删除的记录之所以不立即从磁盘上移除,是因为移除它们之后把其他的记录在磁盘上重新排列需要性能消耗,所以只是打一个删除标记而已,所有被删除掉的记录都会组成一个所谓的 垃圾链表 ,在这个链表中的记录占用的空间称之为所谓的 可重用空间
      • next_record 从当前记录的真实数据到下一条记录的真实数据的地址偏移量,第一条记录的 next_record 值为 32 ,意味着从第一条记录的真实数据的地址处向后找 32 个字节便是下一条记录的真实数据。1

数据页

数据页:

  • InnoDB 将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为 16 KB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。
  • 结构:

2
3
4
4

数据页里每行记录:InnoDB始终会维护一条记录的单链表(next_record),链表中的各个节点是按照主键值由小到大的顺序连接起来的。

Page Directory 页目录:

  • 所有正常的行记录会划分几个组,最后一条记录(也就是组内最大的那条记录)的头信息中的 n_owned 属性表示该记录拥有多少条记录,将每个组的最后一条记录的地址偏移量单独提取出来按顺序存储到靠近 页 的尾部的地方。这个地方就是所谓的 Page Directory。页面目录中的这些地址偏移量被称为
    在这里插入图片描述
  • 主键查找记录:通过二分法确定该记录所在的槽,并找到该槽中主键值最小的那条记录,通过记录的 next_record 属性遍历该槽所在的组中的各个记录。

Page Header(页面头部):

  • 数据页中存储的记录的状态信息,比如本页中已经存储了多少条记录,第一条记录的地址是什么,页目录中存储了多少个槽等等。5

File Header(文件头部)

  • 这个页的编号是多少,它的上一个页、下一个页等…
  • 每个数据页的 File Header 部分都有上一个和下一个页的编号,所以所有的数据页会组成一个 双链表6

File Trailer:页完整性检查。

总: 各个数据页可以组成一个 双向链表 ,而每个数据页中的记录会按照主键值从小到大的顺序组成一个 单向链表 ,每个数据页都会为存储在它里边儿的记录生成一个页目录 ,在通过主键查找某条记录的时候可以在 页目录 中使用二分法快速定位到对应的,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。
6

索引:

索引背景:

  • 主键索引查找数据:以在 页目录 中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录
  • 普通列查找数据:因为在数据页中并没有对非主键列建立所谓的 页目录 ,所以我们无法通过二分法快速定位相应的 槽,只能从最小记录开始遍历查询,一页接一页
  • 目的:为快速定位记录所在的数据页而建立一个别的目录
    • 下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值。
    • 在对页中的记录进行增删改操作的过程中,我们必须通过一些诸如记录移动的操作来始终保证这个状态(页分裂
  • 页目录(索引) -基础概念
    • 页的用户记录中最小的主键值(key)
    • 页号(page_no)
    • record_type :0 :普通的用户记录、1 :目录项记录、2 :最小记录、3 :最大记录
    • 查找主键为20的记录时,1 5 12 209 二分法到 12,找到页9 单链表顺着找到20
      在这里插入图片描述
  • 当数据多起来后,页目录也多起来了,为快速定位 目录项记录,为目录项再 建一个页目录,形成层级
    在这里插入图片描述
    2

由↑ 此可见 由数据页 组成了一个类似 树的结构 B+树

  • 实际用户记录其实都存放在B+树的最底层的节点上,这些节点也被称为 叶子节点 或 叶节点 ,其余用来存放 目录项 的节点称为 非叶子节点 或者 内节点 ,其中 B+ 树最上边的那个节点也称为 根节点

聚簇索引:由 InnoDB 存储引擎自动创建

  • 叶子节点存储了完整的用户记录(所有列)
  • 页内的记录是按照主键的大小顺序排成一个单向链表、也是根据页中用户记录的主键大小顺序排成一个双向链表、同一层次中的页也是根据页中目录项记录的主键大小顺序排成一个双向链表
  • 聚簇(索引即数据,数据即索引)

二级索引:普通列的索引创建。

  • 该列值+主键再建一个B+树,以该列的大小进行记录和页的排序,类似主键索引
  • 以该列值+主键 新建一个 根节点
  • 只不过叶子节点不是完整的数据记录,需要用主键回表一次,查询完整的记录,如果索引覆盖则不需要了(索引下推

联合索引:以同时以多个列的大小作为排序规则,也就是同时为多个列建立索引,组成一个新的B+树

  • c2、c3 建立联合索引,目录项记录 都由 c2 、 c3 、 页号 这三个部分组成。
  • 记录先按照 c2 列的值进行排序,如果记录的 c2 列相同,则按照 c3 列的值进行排序
  • 叶子节点由 c2、c3、主键组成,查找完整记录再回表
  • 最左匹配:idx_c2_c3_c4 建立联合索引,是先按c2值排序c2值相同再按c3排序以此类推,如果查询时不包含c2,则无法命中,无从找起啊。
    • 如果我们想使用联合索引中尽可能多的列,搜索条件中的各个列必须是联合索引中从最左边连续的列

匹配列前缀(字符列索引):

  • 字符排序时,先比较字符串的第一个字符,第一个字符小的那个字符串就比较小,两个字符串的第一个字符相同,那就再比较第二个字符,字符串的前n个字符,也就是前缀都是排好序的。
  • SELECT * FROM person_info WHERE name LIKE 'As%'; 这样查询能更好匹配索引
  • create index idx_name ON table_name (column_name(length)); 只索引字符串值的前缀的策略,部分场景适用

索引代价:

  • 空间上,每建立一个索引都要为它建立一棵 B+ 树,每一棵 B+ 树的每一个节点都是一个数据页,一个页默认会占用 16KB 的存储空间,一棵很大的 B+ 树由许多数据页组成。
  • 性能消耗上, 索引列的值从小到大的顺序排序而组成了双向链表,每次对表中的数据进行增、删、改操作时,都需要去修改各个 B+ 树索引

索引使用:

  • 多列排序时,order by c1,c2 此时有索引inx_c1_c2,会直接命中索引,直接回表取出该索引中不包含的列就好了
    • 注意查询列包含c1,不能 desc、asc混用
  • 要想使用索引进行排序操作,必须保证索引列是以单独列的形式出现,而不是修饰过的形式,类似 ORDER BY UPPER(name)
  • 分组查询时,分组顺序和B+ 树中的索引列的顺序是一致的
  • 只为用于搜索、排序或分组的列创建索引
  • 为基数大(不一致的值)列创建索引

读 “从根儿上理解MySQL” 文章部分内容后,归纳记录一波。
在这里插入图片描述

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

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

相关文章

git 的使用

git reset详解-CSDN博客 git reset 命令详解 git revert命令详解。-CSDN博客 关于Git分支中HEAD和Master的理解 - 知乎 (zhihu.com) 一文带你精通 Git(Git 安装与使用、Git 命令精讲、项目的推送与克隆)-CSDN博客 Git 常用操作(5&#xff…

SpringMVC上传下载文件解读

知识点 文件上传(File Upload): 创建一个控制器方法,使用 MultipartFile 参数来接收上传的文件。在 Spring 配置文件中配置一个 MultipartResolver,常用的实现类是 CommonsMultipartResolver。在 MultipartResolver …

ORDER BY和ROW_NUMBER() OVER (ORDER BY ...)区别?SQL

在 SQL 查询中, ORDER BY 子句用于指定排序的字段以及排序的顺序(升序或降序), 而 ROW_NUMBER() OVER (ORDER BY ...) 则用于为每一行分配一个唯一的序号,并且这个序号是基于指定的排序字段和排序顺序计算的。当然&a…

laravel8模块化开发laravel-modules

laravel8模块化开发laravel-modules 在laravel目录下打开git输入两行命令 $ composer require nwidart/laravel-modules $ php artisan module:make Admin 这个Admin就是文件名

day 18二叉树(五)

day18 代码随想录 2023.12.16 1. 513找树左下角的值 这道题很直观的就是想到层序遍历,最后一层的第一个节点值就是我们需要的,而且很偷懒的是,不用判断是不是最后一层,每一层第一个节点值都保存,会覆盖,最…

Mybatis配置-类型别名(typeAliases)

在Java中&#xff0c;类型别名&#xff08;Type Alias&#xff09;是一个用于简化某个类型的名称的方式。它在XML配置中特别有用&#xff0c;可以减少在全限定类名上繁琐的重复输入。例如&#xff1a; <typeAliases><typeAlias alias"Author" type"do…

grep -B指定输出前置行

要在grep命令输出关键字所在行的同时&#xff0c;再输出关键字的上两行&#xff0c;可以使用grep的-B选项来指定前置行数。下面是一个示例的代码&#xff1a; grep -B 2 "Unsuccessful" shyn在这个示例中&#xff0c;我们使用grep命令过滤出包含"Unsuccessful&q…

用Pyinstaller打包深度学习算法为独立的可执行程序

前言&#xff1a;随着深度学习算法的流行&#xff0c;在传统工业软件计算领域&#xff0c;传统算法逐渐被深度学习算法给代替&#xff0c;但由于基于python的深度学习算法十分依赖python环境以及例如Pytorch、Scikit-learning、Keras等机器学习库&#xff0c;将深度学习算法运用…

西南科技大学数字电子技术实验五(用计数器设计简单秒表)预习报告

一、计算/设计过程 说明&#xff1a;本实验是验证性实验&#xff0c;计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程&#xff0c;越详细越好。用公式输入法完成相关公式内容&#xff0c;不得贴手写图片。&#xff08;注意&#xff1a;从抽象公式直接得出结…

UE5 PlaceActor

⚠️ 重点 PlaceActors 需在引擎初始化之后 但&#xff0c;单为这一个功能&#xff0c;更改整个模块的启动顺序&#xff0c;也不太划算 更好的办法是&#xff0c;启动顺序保持正常&#xff08;如"LoadingPhase": "Default" &#xff09;&#xff0c;然后…

Java EE 多线程之线程安全的集合类

文章目录 1. 多线程环境使用 ArrayList1. 1 Collections.synchronizedList(new ArrayList)1.2 CopyOnWriteArrayList 2. 多线程环境使用队列2.1 ArrayBlockingQueue2.2 LinkedBlockingQueue2.3 PriorityBlockingQueue2.4 TransferQueue 3. 多线程环境使用哈希表3.1 Hashtable3.…

innerHTML、innerText、textContent有什么区别

innerHTML、innerText、textContent有什么区别 在 HTML 中&#xff0c;innerHTML、innerText、 和textContent是 DOM&#xff08;文档对象模型&#xff09;的属性。它们允许我们读取和更新 HTML 元素的内容。 但它们在包含的内容以及处理 HTML 标签的方式有不同的行为。 读完…

分布式事务seata使用示例及注意事项

分布式事务seata使用示例及注意事项 示例说明代码调用方&#xff08;微服务A&#xff09;服务方&#xff08;微服务B&#xff09; 测试测试一 &#xff0c;seata发挥作用&#xff0c;成功回滚&#xff01;测试二&#xff1a;处理feignclient接口的返回类型从Integer变成String,…

【Spring Boot】快速入门

一、引言 1、什么是spring boot&#xff1f; Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。通过这种方式&#xff…

LEFT JOIN 避坑指南

left join 通俗的解释&#xff1a;以左表为主表&#xff0c;返回左表的所有行&#xff0c;如果右表中没有匹配&#xff0c;则依然会有左表的记录&#xff0c;右表字段用null填充。 准备数据 假设有一个班级管理应用&#xff0c;有一个表classes&#xff0c;存了所有的班级&am…

【RocketMQ-Install】Windows 环境下安装 RocketMQ 及基础命令的使用

【RocketMQ-Install】Windows 环境下 安装本地 RocketMQ 及基础命令的使用 1&#xff09;下载 RocketMQ 安装包1.1.官网下载&#xff08;推荐&#xff09;1.2.Git 下载1.3.安装环境要求说明 2&#xff09;Windows 安装3&#xff09;基础命令测试 1&#xff09;下载 RocketMQ 安…

芯知识 | 什么是音频蓝牙播放语音芯片?

随着科技的不断进步&#xff0c;音频蓝牙播放语音芯片成为嵌入式音频系统中备受关注的创新解决方案。本文将深入解析什么是音频蓝牙播放语音芯片&#xff0c;以及其在实现无线音频体验方面的重要作用。 一、什么是音频蓝牙播放语音芯片&#xff1f; 音频蓝牙播放语音芯片是一…

Java:SpringBootTest指定profile

示例 指定使用test环境配置 SpringBootTest ActiveProfiles("test") public class APiServiceImplTest {}参考 spring boot-JUnit Test指定profile

多分类预测 | MATLAB实现CNN-LSTM-Attention多输入分类预测

分类预测 | MATLAB实现CNN-LSTM-Attention多输入分类预测 分类效果 需要源码和数据的私信&#xff08;微微有偿取哦&#xff09;