InnoDB之记录结构
1.表中的数据到底存到了哪里?
2.以什么格式存放的?
3.MySQL是以什么方式来访问的这些数据?
0. 前置知识
MySQL服务器上负责对表中数据的读取和写入工作的部分是存储引擎。
不同存储引擎中数据存储格式一般不同,本文将回答InnoDB记录下是以何种格式存在的。
InnoDB是一个将表中的数据存储到磁盘上的存储引擎,因为读写磁盘速度缓慢,为了减少读写磁盘次数,InnoDB采取的方法是:将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为 16 KB。
1.InnoDB的四种行格式
1.Compact
2.Redundant
3.Dynamic
4.Compressed
MySQL指定行格式命令如下:
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称
ALTER TABLE 表名 ROW_FORMAT=行格式名称
1.1Compact行格式
变长字段指拥有变长的数据类型(如VARCHAR(M) 、VARBINARY(M) 、各种TEXT 类型,各种BLOB 类型)的列,在Compact 行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放,且只存储非NULL的列内容占用的长度。
注:采用变长字符集时,该列占用的字节数也会被加到变长字段长度列表。
NULL值列表存储记录中所有值为NULL的列,将每个允许存储NULL的列对应一个二进制位,二进制位按照列的顺序逆序排列,如果使用的二进制位个数不是整数个字节,高位补0成整数个字节。
记录头信息
固定5个字节,不同位代表不同意思。
delete_mask(1bit): 标记该记录是否被删除
min_rec_mask (1bit): B+树的每层非叶子节点中的最小记录都会添加该标记
n_owned(4bits):表示当前记录拥有的记录数
heap_no(13bits):表示当前记录在记录堆的位置信息
record_type(3bits):表示当前记录的类型,0 表示普通记录,1表示B+树非叶子节点记录, 2 表示最小记录, 3表示最大记录
next_record(16bits):表示下一条记录的相对位置
记录的真实数据,除了自定义的列数据外,MySQL会为每个记录默认添加一些列(隐藏列):
列名 | 是否必须 | 占用空间 | 描述 |
---|---|---|---|
DB_ROW_ID | 否 | 6B | 行ID,唯一标识一条记录 |
DB_TRX_ID | 是 | 6B | 事务ID |
DB_ROLL_PTR | 是 | 7B | 回滚指针 |
注:InnoDB主键生成策略:
用户定义–>无则选取一个Unique键–>无则添加DB_ROW_ID。
1.2 Redundant行格式
注:MySQL5.0之前用的一种行格式,略过。
1.3 Dynamic 和 Compressed行格式
和Compact 行格式挺像,只不过在处理行溢出数据时不同,它们不会在记录的真实数据处存储字段真实数据的前768 个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址。Compressed行格式会采用压缩算法对页面进行压缩。