MySQL是基于磁盘进行数据存储的关系型数据库, 所有的数据和索引都以磁盘文件的方式存储, 在有需要时载入内存读取。MySQL支持多种存储引擎,不同的存储引擎保存的文件不同。
InnoDB是MySQL使用最为广泛的存储引擎,下面我们以InnoDB引擎为例来说明。
当我们创建一个数据库表时,InnoDB会创建三个文件。其中,ibd后缀的文件是对表数据和索引实际存储的文件,也称为表空间文件。
表空间文件的结构由段、区、页、和行组成。
数据库表中的记录都是按行进行存放的,每行记录根据不同的行格式,有不同的存储结构。以Compact行格式为例,一条记录的存储可以分为两部分,分别是“额外信息”和“真实数据”。 额外信息用来描述记录,分为变长字段列表、NULL值列表和记录头信息。
虽然记录是按照行来存储的,但考虑到效率,数据库的读写并不以行为单位,而是以页为单位,一个页中可以存储多个行记录。页的大小默认为16KB,也就是数据库一次最少从磁盘中读取16KB的内容到内存,一次最少把内存中16KB的内容刷新到磁盘。
区是比页大一级的存储结构,一个区会分配64 个连续的页。因为页大小默认是16KB,所以一个区的大小是 64个16KB,也就是1MB。
段由一个或多个区组成,区在文件系统是一个连续分配的空间,不过在段中不要求区与区之间是相邻的。段是数据库中的分配单位,不同类型的数据库对象以不同的段形式存在。当我们创建数据表、索引的时候,就会创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段。
表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成。
对于一行数据如何存放,我们需要重点关注变长字段和NULL值。MySQL支持一些变长的数据类型,比如varchar(n),变长字段中存储多少字节数据是不固定的,所以我们存储真实数据的时候,需要把这些数据占用的字节数也存起来。
在Compact行格式中,把所有变长字段真实数据占用的字节长度,按照记录列的逆序方式存放在记录的开头部位,形成一个变长字段长度列表。注意当数据表没有变长字段时,比如全部都是int类型字段,这时候表里的行格式就不会有变长字段长度列表。
另外,Compact行格式还会把可以为NULL的列统一管理起来,以记录列的逆序方式存放在一个NULL值列表中。标示数据是否为NULL使用一个二进制位表示,1为NULL,0为非NULL,注意,如果表中没有允许存储 NULL 的列,则 NULL值列表也不存在。
标签:存储,记录,数据库,内核,MySQL,NULL,变长 From: https://www.cnblogs.com/o-O-oO/p/18608732原创 coderxiaozhi 编程十万问