1. 数据页
innodb存储引擎,把数据组织成一页一页的概念,每一页有16kb,然后每次加载磁盘的数据到内存的时候,是至少加载一页数据进去的,甚至是多页数据进去。
2. 一行数据在磁盘是如何存储的
行格式,使用COMPACT格式
CREATE TABLE table_name (columns) ROW_FORMAT=COMPACT
ALTER TABLE table_name ROW_FORMAT=COMPACT
这种格式下,数据存储的格式类似如下:
[变长字段的长度列表],[null值列表],[数据头],[column1的值,column2的值,columnn的值......]
除了每一个字段的值以外,还包含了一些额外的信息,这些额外的信息就是用来描述这一行数据的。
2.1. 长信息的存储
类如:字段变长与定长混合的表: varchar(10) varchar(5) varchar(20) CHAR(1) CHAR(1)
存储内容为:hello hi hao a a
变长的字段长度分别为:0x05 0x02 0x03
定长字段的长度列表是逆序放的,猜测逆序放是通过压入栈的方式,然后出栈正向读取
对应存储为: [0x03 0x02 0x05] [null值列表] [数据头] [hello hi hao a a]
2.2. NULL值处理
NULL值是以二进制bit为来存储的,表结构如下:
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
变长的字段长度:0x04(jack) 0x09(xx_school)
因为表中4个字段可以为null(address,gender,job,school),对应上面的数据为1010,即1是null(address,job),0是非null(gender,school),实际存储是倒序同时是补足8位的。
所以磁盘上的存储为: [0x09 0x04] [00000101] [头字段] [jack m xx_school]
2.3. 40bit的头字段
第一个和第二个bit为,预留位,没有意义
第三位是delete_mask,标识这行数据是否删除
第四位min_rec_mask,b+树里面每一层的非叶子节点的最小值
第五位到第八位,n_owbed,记录数
接下来的13位 heap_no,当前这行数据在记录堆里的位置
然后3位是record_type,数据类型 0:普通类型 1:B+树非叶子节点 2:最小值 3:最大值
16位next_record,下一条指针地址
2.4. 其他字段
DB_ROW_ID,这个行的唯一标识,如果没有指定主键,默认加的ROW_ID为主键
DB_TRX_ID,事务ID
DB_ROLL_PTR,回滚指针
3. 行溢出
当最后的真实数据端存储实际数据的时候,如果出现的内存过大,列如存储了txt类型的数据,会导致超过单页16kb的限制,就会出现行溢出的现象,即数据行页存储。
4. 表空间
我们平时创建的那些表都是有对应的表空间的,每个表空间就是对应磁盘上的数据文件,在表空间里有很多组数据区,一组数据区是256个数据区,每个数据区包含了64个数据页,是1MB,然后表空间的第一组数据区的第一个数据区的头三个数据页,都是存放特殊信息的。
当我们执行crud操作的时候,就是从磁盘上的表空间的数据文件里,去加载一些数据页出来到buffer pool的缓存页里去使用。