mysql 表的创建时间一直在表_MySQL 表

本章将描述 InnoDB 存储引擎中数据在表中是如何组织和存放的,这是关系型数据库模型的核心。

索引组织表

前面提到,InnoDB 存储引擎都是根据主键组成的,即使没有显式地创建主键,InnoDB也会选择或者创建主键,这种存储方式称为索引组织表。

当创建表没有显示定义主键,InnoDB 存储引擎主键确定方式:

  • 首先判断表中是否有非空的唯一索引,如果有或有多个,选择第一个定义的唯一索引为主键。

  • 如果不符合上面条件,InnoDB 存储引擎主动创建一个 6 字节大小的 _rowid 作为主键。

InnoDB 逻辑存储结构

InnoDB 存储引擎中,所有的数据都被逻辑的存放到一个空间,被称为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成,InnoDB 存储引擎的逻辑存储结构如下图所示:

4e91b4cf0797701b86c3ce4c5bace9d2.png

表空间是 InnoDB 存储引擎逻辑结构的最高处,所有数据都存放在表空间中。默认情况下InnoDB只有一个共享表空间 ibdata1,即所有的数据都存放在这个表空间中。如果用户启用了innodb_file_per_table,则每张表内的数据可以单独放到一个表空间内。需要注意的是,如果启用了innodb_file_per_table 参数,每张表的表空间内存放的只是数据、索引和插入缓冲 Bitmap 页,其他类的数据,如回滚信息,插入缓冲索引页、系统事务信息,二次写缓冲等还是存放在原来的共享表空间内。所以即便开启了 innodb_file_per_table 之后,共享表空间还是会不断增大的。

表空间由各个段组成,如数据段、索引段、回滚段等。InnoDB 存储引擎是索引组织表,数据即索引,故数据段即为 B+ 树叶子节点,索引段即为 B+ 树非叶子节点。InnoDB 存储存储引擎中段的管理是存储引擎自身完成的,无需人工管理。

区是连续页组成的空间,一个区的大小为 1MB,默认情况 InnoDB 存储引擎页的大小为16KB,即一个区一共有 64 个连续的页。为了保证区的连续性,InnoDB 存储引擎每次从磁盘申请 4~5 个区。

InnoDB 存储引擎中页是磁盘管理的最小单位,页大小一经设置不可以对其再次修改,常见的页类型有:

  • 数据页(B-tree Node)

  • undo页(undo Log Page)

  • 系统页(System Page)

  • 事务数据页(Transaction Page)

  • 插入缓冲位图页(Insert Buffer Page)

  • 插入缓冲空闲列表页(Insert Buffer Free List)

  • 未压缩的二进制大对象页(Uncompressed BLOB Page)

  • 压缩的二进制大对象页(compressed BLOB Page)

InnoDB 存储引擎是面向列的(row-oriented),即数据按行存放,每页存放的行记录页是有硬性定义的。最多允许存放 16K/2-200 行的记录,即 7992 行记录。

InnoDB 数据页结构

页是 InnoDB 存储引擎管理数据库最小的磁盘单位,页类型为 B-tree Node 的页存放的是表中行的实际数据。

8892b4ad2ed239e8842e5a9d87d71f0a.png

如上图所示,InnoDB数据页由七个部分组成:

  • File Header(文件头)

  • Page Header(页头)

  • Infimun + Supremum Records

  • User Records(用户记录)

  • Free Space(空闲空间)

  • Page Directory(页目录)

  • File Trailer(文件结尾信息)

File Header、Page Header、File Trailer的大小是固定的,用来标示该页的一些信息。其余部分为实际的行存储空间,因此大小是动态的。

行记录格式

InnoDB 存储引擎数据记录是以行的形式存储的,页中保存着表中的一行行数据。InnoDB 存储引擎提供了 Compact 和 Redunant 两种格式来存储行记录,默认是 Compact 行格式,Redundant 格式是为了兼容之前版本。

Compact 行记录格式是 MySQL 5.0 引入的,设计目的是高效存储数据,简单的说,一个页中能存放的行记录越多,其性能就越高。

87679f3c0e835ed063206b7b4a99b067.png

Compact 行记录格式首部是一个非 NULL 的变成字段列表,并且是按照列的顺序逆序放置的。其长度为:若列的长度小于 255 字节,用 1 字节表示;若列的长度大于 255 个字节,用 2 字节表示。变长字段长度列表之后的部分是 NULL 标志位,标识该行记录中是否有 NULL 值,该部分占用 1 字节长度。第三步部分是记录头信息,固定占用 5 字节(40 位),每位含义如下:

a22d3c2d21d5c31b7016ed58c3902c8f.png

最后部分就是实际存储每个列的数据,其中 NULL 不占用该部分空间,而且每行记录除了用户定义的列外还有两个隐藏列,事务 ID 列和回滚指针列,分别是 6 字节 和 7 字节大小,如果没有显式定义主键,每行还会增加一个 6 字节的 _rowid 列。

InnoDB 存储引擎可以将一条记录中的某些数据存放在真正的数据页之外,一般是 BLOB、LOB 这类大对象列类型。但是这样理解是比较粗暴的,BLOB 也可以不把数据放到溢出页,而且即便是 VARCHAR 列数据类型页也可能被存放到行数据溢出页。我们知道 InnoDB 存储引擎是索引组织表,即 B+树结构,如果让 B+ 树索引有意义,那么一个数据页应该至少存在两条行记录,即如果数据页大小为 16K(16384字节),那面至少每条行记录小于 8192 字节才可能存放到数据页,实际测试是 VARCHAR 列数据类型存放溢出页长度阈值为 8098字节。

InnoDB 1.0.x 版本开始引入了两种新的行记录格式:Compressed 和 Dynamic,这两种数据格式在存放 BLOB 列数据类型时采用完全的行溢出方式。Compressed 行记录另一个功能是存储在其中的数据会以 zlib 算法压缩,可以更有效存储大字段数据类型。


公众号文章同步github。

本文地址:github.com/lazecoding/Note/blob/main/note/articles/mysql/表.md

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值