1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」

1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」本章将重点分析表的物理存储特征,即数据在表中是如何组织存放的。也就是说,表就是关于特定实体的数据集合,这也是关系型数据库模型的核心。 4.1 索引组织表 在 InnoDB存储引擎中,表都是按照主键顺序

1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式

本章将重点分析表的物理存储特征,即数据在表中是如何组织存放的。也就是说,表就是关于特定实体的数据集合,这也是关系型数据库模型的核心。

4.1 索引组织表

在 InnoDB存储引擎中,表都是按照主键顺序存放的,这样的存储方式的表称为索引组织表。如果创建表时没有显式的定义主键,则按照如下方式选择或创建主键:

  • 判断表中是否有非空的唯一索引(Unique NOT NULL),如果有,则该列即为主键,如果有多个非空的唯一索引,则选择第一个定义索引的作为主键。
  • 如果不符合上述条件,自动创建一个6字节的指针

_rowid 用于查看单个列作为主键的情况,对于多列,无能为力。

4.2 InnoDB逻辑存储结构

从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑的存放在一个空间中,称之为表空间。表空间由段(segment)、区(extent)、页(page/block 块)组成。

1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」

4.2.1 表空间

可以看到,InnoDB存储引擎逻辑结构的最高层,所有数据都在表空间中。默认情况下,InnoDB有一个共享表空间(ibdata1),如果启用了参数 innodb_file_per_table,则每张表的数据都可以单独放到一个表空间内。但每张表的表空间内存放的只是数据、索引和插入缓冲 bitmap页。其他类型的数据,如回滚(undo)信息、插入缓冲索引页、系统事务信息、二次写缓冲(doublewrite buffer)还在共享表空间。

  InnoDB存储引擎不会再执行 rollback 时去收缩 ibdata1 这个空间。虽然 InnoDB 不会回收这个空间,但是会自动判断这些undo 信息是否还需要,如果不需要,则会将这些空间标记为可用空间,供下次undo使用。

4.2.2 段

从上图可知,表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等。其中数据段即为B+树的叶子节点(Leaf Node Segment),索引段即为 B+树的非索引节点(Non-leaf node segment),回滚段后续单独介绍。

4.2.3 区

区是连续的页组成的空间,在任何情况下,都是1MB。默认情况下,InnoDB存储引擎页的大小为 16 KB,即一个区中一共有 64 个连续的页。InnoDB 1.2.x 新增了参数 innodb_page_size ,通过该参数可以将默认页的大小设置为4K,8K,但页中的数据库不是压缩,但无论页的大小怎么变化,区的大小总是1MB

  用户启用了参数 innodb_file_per_table后,创建的表的默认大小是96KB,区中有64个连续的页,应该是1M才对啊?因为在每个段开始时,先用32个页大小的碎片页(fragment page)来存放数据,在使用完这些页之后才是64个连续页的申请。这样做的目的是,对一些小表,或undo这类的段,可以在开始时申请较少的空间,节省磁盘开销。

4.2.4 页

页是InnoDB磁盘管理的最小单位 ,默认一个页大小为16 KB。InnoDB 常见的页类型有:

  • 数据页(B-tree Node)
  • undo页(undo log page)
  • 系统页(system page)
  • 事务数据页(Transaction system page)
  • 插入缓冲位图页(insert buffer bitmap)
  • 插入缓冲空闲列表页(insert buffer Free list)
  • 未压缩的二进制大对象页(Uncompressed BLOB page)
  • 压缩的二进制大对象页(compressed BLOB page)

4.3 InnoDB行记录格式

InnoDB 存储引擎的记录是以行的方式存储的。InnoDB提供了 compact 和 redundant 两种格式来存放行记录数据,Redundant 格式是为了兼容之前版本而保留的。在 MySQL 5.1 中,默认设置为 Compact 格式。

4.3.1 compact 行记录格式

compact 行记录的存储方式如下所示:
1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」

 

compact 行记录格式的首部是一个非 NULL 的变长字段长度列表。并且是按照列的顺序逆序放置的。

第二个部分是NULL标志位,该位指示了该行数据中是否有NULL值,有则用1标识。

接下来是记录头信息(record header),固定占用5个字节,40位,每位的含义如下:

名称 大小(bit) 描述
0 1 未知
0 1 未知
deleted_flag 1

该行是否被删除

min_rec_flag 1 为1,表示该记录是预先被定义为最小的记录
n_owned 4

该记录拥有的记录数

heap_no 13 索引堆中该记录的排序记录
record_type 3 记录类型,000标识普通,001标识B+树节点指针,010标识 Infimum,011标识Supremum,1xx标识保留
next_record 16 页中下一条记录的相对位置
total 40  

record header 最后两个字节是 next_record,代表下一个记录的偏移量,即当前记录的位置加上偏移量就是下条记录的起始位置。所以InnoDB存储引擎是在页内部是通过一种链表的结构来串联各个行记录的

 

最后的部分就是实际每个列的数据,NULL不占用该部分任何空间,即NULL除了占用NULL标志位,实际存储不占用任何空间。另外,每行数据除了用户定义的列外,还有两个隐藏列,事务ID列和回滚指针列。若表没有定义主键,还会增加一个6字节的rowid列。

4.3.2 Redundant 行记录格式

Redundant 是 MySQL5.0 版本之前 InnoDB的行记录存储方式。存储格式如下:

1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」

 

不同于compact,首部是一个字段长度偏移列表,按照列的顺序逆序放置的。

第二个部分是记录头信息,不同于 compact格式,Redundant 的记录头占用6个字节,其中 n_fields 值代表一行中列的数量,占用10 位,很好的解释了为什么 MySQL数据库一行支持最多的列为 1023

名称 大小(bit) 描述
0 1 未知
0 1 未知
deleted_flag 1

该行是否被删除

min_rec_flag 1 为1,表示该记录是预先被定义为最小的记录
n_owned 4

该记录拥有的记录数

heap_no 13 索引堆中该记录的排序记录
n_fields 10 记录中列的数量
1byte_offs_flag 1 偏移列表为1字节还是2个字节
next_record 16 页中下一条记录的相对位置
total 48  

Redundant 格式 的 CHAR 类型的NULL值需要占用空间。

4.3.3 行溢出数据(待续……)

4.3.4 Compress 和 Dynamic 行记录格式(待续……)

4.3.5 CHAR 的行结构存储(待续……)

4.4 InnoDB数据页结构

InnoDB 数据页有以下7部分组成:

  • File Header(文件头)
  • Page Header(页头)
  • Infimum 和 Supremum Records
  • User Records(用户记录,即行记录)
  • Free Space(空闲空间)
  • Page Directory(页目录)1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」
  • File Trailer(文件结尾信息)

1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」

4.4.1 File Header

4.4.2 Page Header

4.4.3 Infimum 和 Supremum Record

在InnoDB存储引擎中,每个数据页中有两个虚拟的行记录,用来界定记录的边界。Infimum 是比该页中任何主键值都要小的值。Supremum 指的是比任何可能打的值还要大的值。这两个值在页创建时被建立,并且任何情况下不会删除。

1. MySQL体系结构——InnoDB存储引擎表、页结构、行记录格式「终于解决」

 4.4.4 User Record 和 Free Record

User Record 是实际存储行记录的内容,而 Free Space 指的是空闲空间,也是个链表数据结构。在一条记录被删除后,会加入到空闲链表中。

4.4.5 Page Directory

页目录中存放了记录的相对位置,有时候,这些记录指针被称为Slots(槽)或目录槽(Directory Slots),InnoDB 存储引擎的槽是一个稀疏目录,即一个槽中有多个记录。

在 InnoDB中Page Directory 是稀疏目录,二叉查找的结果只是粗略的结果,因此 InnoDB 必须通过 record Header 中的 next_record 来继续查找相关记录。同时 Page Directory 很好的解释了 record header 中的 你_ownedzhi的含义,因为这些记录并不包含在 page Directory中

需要牢记的是,B+ 树索引本身并不能找到具体的一条记录,能找到的只是该记录所在的页。数据库把页载入内存,然后通过page Directory 再进行二叉查找。

4.4.6 File Trailer

为了检测页是否已经完整的写入磁盘(如可能发生的写入过程中的磁盘损坏,机器关机等),InnoDB的页中设置了 File Trailer 部分。

4.5 Name File Formats 机制(待续……)

4.6 约束

4.6.1 数据完整性

一般来说,数据完整性有以下三种形式:

  1. 实体完整性:保证表中有一个主键,用户可通过定义 Unique Key 或 Primary Key约束来保证
  2. 域完整性:保证数据每列的值满足特定的条件,如合适的数据类型,外键约束,编写触发器,default约束
  3. 参照完整性:保证两张表之间的关系,如外键或触发器

4.6.2 约束和索引的区别

当用户创建了一个唯一索引就创建了一个唯一的约束。但是约束更像是一个逻辑的概念,用来保证数据的完整性。而索引是一个数据结构,既有逻辑概念,也代表这物理存储的方式。

4.7 视图

视图是一个命名的虚表,,由一个SQL 查询来定义,可以当做表使用,视图中的数据没有实际的物理存储。视图在一定程度上起到了一个安全层的作用。

虽然视图是一个虚表,但用户可以对某些视图进行更新操作,本质就是通过视图的定义来更新基本表。

4.8 分区表(待续……)

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/8997.html

(0)
上一篇 2023-02-17
下一篇 2023-02-17

相关推荐

  • Python清空文件内容的方法

    Python清空文件内容的方法在日常工作和开发中,我们时常需要操作文件。文件的读取、写入是比较常见的操作。但是在一些特殊情况下,我们需要清空文件内容,这时我们就需要学会如何清空文件。

    2024-08-06
    30
  • 使用Python脚本循环遍历目录中的文件

    使用Python脚本循环遍历目录中的文件在许多数据处理和分析任务中,需要对大量的文件进行处理。自动化脚本可以减轻手动任务的负担,其中最常见的脚本之一就是循环遍历一个目录中的所有文件。

    2024-03-25
    79
  • Python Assert:优化代码调试与测试

    Python Assert:优化代码调试与测试Python Assert是Python中的一种断言语句,用于在代码中进行自动化测试。通过在代码中插入assert语句,可以对代码做出各种前置条件的检查,以确保代码的正确性。当assert语句的条件返回False时,程序将会中止并抛出异常,以提醒开发人员代码存在问题。

    2024-03-15
    76
  • mysql数据库索引数据结构_数据库中索引的概念

    mysql数据库索引数据结构_数据库中索引的概念一、什么是索引 索引是mysql数据库中的一种数据结构,就是一种数据的组织方式,这种数据结构又称为key 表中的一行行数据按照索引规定的结构组织成了一种树型结构,该树叫B+树 二、为何要用索引 优化查

    2023-05-05
    156
  • SpringBoot随笔-SpringBoot集成Druid[通俗易懂]

    SpringBoot随笔-SpringBoot集成Druid[通俗易懂]1.Druid是什么 Druid是Java语言中最好的数据库连接池之一,Druid能够提供强大的监控和扩展功能。 2.Druid连接池的优点: 强大的监控特性,通过Druid提供的监控功能,可以清楚知

    2023-03-06
    164
  • mysql 8.0 配置文件my.cnf中文注解【转载】[通俗易懂]

    mysql 8.0 配置文件my.cnf中文注解【转载】[通俗易懂]########################################################################### ## my.cnf for MySQL 8.0.

    2023-04-26
    159
  • Python字典值排序操作

    Python字典值排序操作在Python编程中,字典(Dictionary)是一种重要的数据类型,它以键值对的形式来存储和管理数据。在实际应用中,可能需要对字典的值进行排序。本文将讲解Python字典值排序操作的相关知识。

    2024-09-09
    21
  • Doris开发手记4:倍速性能提升,向量化导入的性能调优实践

    Doris开发手记4:倍速性能提升,向量化导入的性能调优实践最近居家中,对自己之前做的一些工作进行总结。正好有Doris社区的小伙伴吐槽向量化的导入性能表现并不是很理想,就借这个机会对之前开发的向量化导入的工作进行了性能调优,取得了不错的优化效果。借用本篇手记

    2023-06-11
    156

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注