逻辑概念:表、字段、行

物理概念(由大到小):表空间、数据区组、数据区、数据页、数据行

数据行的存储格式:

COMPACT行存储格式为例进行说明:

变长字段的长度列表,NULL值列表,数据头,column01的值,column02的值,column03的值.......

除了每一个字段的值之外,还有一些额外信息,这些额外的信息就是用来描述这一行数据的。

变长字段的存储:

比如varchar(10)类型的字段可以存储hello,可以存储hi

为了方便读取,需要记录变长字段的实际长度,并且逆序存放

比如要存放hello hi hao,实在存放的时候:0x03  0x02  0x05  null值列表 头字段 hello hi hao

NULL字段值的存储:

如果直接存储“NULL”,就很浪费空间,而且没有必要,所以NULL值是以二进制bit位来存储的,如果bit的值是0,说明不是NULL,如果bit的值是1,说明是NULL。

定义表:

CREATE TABLE customer(

Name varchar(10) NOT NULL,

Address varchar(20),

Gender char(1),

Job varchar(30),

School varchar(50)

)ROW_FORMAT=COMPACT;

现在存储一行数据:Jack NULL m NULL xx_school

如果变长字段的值是NULL,那么就不用再变长字段长度列表中存放他的值长度了。

所有允许为NULL的字段都有一个二进制的bit位的值。

NULL值列表同样是逆序存储的,而且是8个bit位的倍数,不足的话高位补0。

实际存放:

0x09 0x04 00000101 头信息 Jack m xx_school

然后对字符串进行字符集编码之后再存储:

0x09 0x04 00000101 头信息 616161 636320 626262656566

隐藏字段:

实际存储一行数据的时候,会在他的真实数据部分,加入一些隐藏字段。

DB_ROW_ID:一个对数据行的唯一标识

DB_TRX_ID:事务ID,说明这是哪个事务更新的数据

DB_ROLL_PTR:回滚指针,用于事务回滚

行溢出:

一个数据页默认大小是16KB,如果一行数据的大小超过了数据页的大小,应该怎么办呢?

比如说一个表里定义了一个varchar(65532)的字段,那也就是65532个字节,远远超过16KB。这个时候,存储这行数据的数据页中,那个字段仅仅一部分在该数据页中,同时包含一个20字节的指针,指向了其他一些数据页,由那些数据页用链表串联起来,存放这个varchar(65532)超大字段里的数据。

mysql procedure 求模 mysql模型_mysql procedure 求模

像TXET、BLOB这种字段的行,都会出现行溢出,然后一行数据就会存储在多个数据页里。

数据页的存储格式:

数据页默认大小位16KB,存储了很多数据行,内部拆分了很多部分,大体上来说包括:文件头、数据页头、最小记录和最大记录、多个数据行、空闲空间、数据页目录、文件尾部

mysql procedure 求模 mysql模型_java_02

文件头占据38个字节,数据页头占据56个字节,最大最小记录占据26个字节,数据行区域大小和空闲区域大小是不固定的,数据目录大小也不固定,文件尾部占据8个字节。

表空间与数据区:

表空间:

每个表都有对应的表空间,在磁盘上都会对应“表明.ibd”这样的磁盘数据文件。

在物理层面,表空间就是磁盘上的数据文件。

数据区:

一个数据区就是连续的64个数据页,每个数据页16KB,所以一个数据区就是1MB。然后256个数据区被划分为一组。

表空间的第一个数据区组的第一个数据区的头三个数据页是存放特殊信息的。

表空间其他数据区组的第一个数据区的头两个数据页,也是存放特殊信息的。

mysql procedure 求模 mysql模型_java_03