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.hqwc.cn/news/277582.html

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

相关文章

PHP微信朋友圈广告植入源码 +提供高效的广告植入解决方案,助力微信朋友圈广告推广

源码介绍 可以无限制帮用户开户,也可以理解为多用户版。 可以管理用户发布文章条数,也可以无限制发布。 用户可以上传多个广告,每个广告分别进行统计展示及点击。 用户一键植入,不用粘贴网址,每篇文章会 分别统计展示…

设计原则 | 接口隔离原则

一、接口隔离原则 1、原理 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。如果强迫客户端依赖于那些它们不使用的接口,那么客户端就面临着这个未使用的接口的改变所带来的变更,这无意间导致了客户程序之…

【MySQL 索引】InooDB 索引实现

1 索引定义 维基百科对数据库索引的定义: 数据库索引是数据库管理系统(DBMS)中的一个排序数据结构, 以协助快速查询和更新数据库表中的数据。 MongoDB对索引的定义: 索引是一种特殊的数据结构, 以有序和便于遍历的形式存储数据集合中特定字段或一组字段…

stable-diffusion-webui(AI绘画)项目实现,即遇到的问题

实现步骤: 为了使环境中的库版本不会乱,导致自己电脑原来一些项目无法运行最好使用虚拟环境 下载miniconda 在搜索中搜所miniconda找到 建立虚拟环境 conda create --name sdwebui python3.10.6 每次运行激活这个虚拟环境 conda activate sdwebui …

天猫数据分析(天猫数据查询平台):11月天猫啤酒市场销售数据分析报告

在酒类市场中,被视作“气氛担当”的啤酒,是派对聚会或者自饮场景中的常客,消费人群广泛,如今,啤酒市场已进入存量时代,市场中啤酒的销售也在稳步增长。 鲸参谋数据显示,今年11月份,天…

Win11 TensorRT环境部署

一、CUDA和CUDNN安装 cuda和cudnn网上有很多安装教程,这里列举了一些,就不详细说了,具体链接如下: csdn.net - CUDA安装教程(超详细) 原创 zhihu.com - 深度学习之CUDACUDNN详细安装教程 tencent.com - C…

vue2使用wangeditor实现数学公式+富文本编辑器

需求: 做一个带有数学公式的富文本编辑器,在网上看了很多,这个最合适,借鉴了wangEditor富文本编辑器 这里面写的是v3的整合富文本编辑器,我照着上面改成了v2的,本文章主要是实现步骤和错误解决,…

找不到mfc100u.dll,程序无法继续执行?三步即可搞定

在使用电脑过程中,我们经常会遇到一些错误提示,其中之一就是“找不到mfc100u.dll”。mfc100u.dll是Microsoft Foundation Class(MFC)库中的一个版本特定的DLL文件。MFC是微软公司为简化Windows应用程序开发而提供的一套C类库。它包…

mybatis-plus雪花算法自动生成ID到前端后精度丢失问题

问题发生 前端接收到后端的数据出现异常,异常如下: 如图这是后端正常返回的数据, 但是点击预览时发现这个id的数据被改变了 这就导致了我通过id去修改相关数据时无法成功 问题原因 id的长度过长(19位),前…

UE4 在编辑器下进行打印 学习笔记

创建WidgetComponent 创建Blueprint Interface 创建接口名字 在WidgetComponent里面使用Tick调用才创建的接口 随便创建一个Actor 在BP里面使用这个接口 在这里搜索它调用 在这里就可以做对应的操作 把组件加到Actor上面 把这个Actor放入场景 就开始打印了

经典深度学习算法【1】:K-近邻算法(KNN)概述

最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类。但是怎么可能所有测试对象都会找到与之完全匹配的训练对象呢,其次就是存在一个测试对象同时与多个训练…

PR模板,复古怀旧电影效果视频制作PR项目工程文件

Premiere复古怀旧电影效果视频制作pr模板项目工程文件下载 这个PR模板以复古城市印象电影质感为特色,结合了电影和数字故障效果。包含6个场景。可以编辑文本、添加媒体和自定义颜色。包含视频教程。4K版本。不需要任何插件。 软件支持:PR2022 | 分辨率&a…