一行记录的存储

MySQL文件存在哪个目录

每创一个database都会在 /var/lib/mysql/ 目录里创一个以database为名的目录,然后保存表结构(t_order.frm)和表数据(t_order.ibd独占表空间文件)的文件都会存在这个目录里。

表空间文件结构

段、区、页、行。InnoDB按(16kb)读写,B+树组织数据,通过双向链表连接,如果以页分配存储空间那么链表中相邻两个页间物理位置不连续,磁盘查询时会有大量随机IO,慢:表数据量大时,为某索引分配空间时按(1MB)为单位分配,对于 16KB 的页来说,连续的 64 个页会被划为一个区,使得链表中相邻页的物理位置也相邻,就能顺序IO。由多个区组成:索引段(B+树非叶子节点区)、数据段(B+树叶子节点区)、回滚段(回滚数据区)。

COMPACT行格式

「记录的额外信息」变长字段长度列表(按照列顺序逆序存:使位置靠前的记录的真实数据和数据对应的字段长度信息可以同时在一个 CPU Cache Line中,提高CPU Cache命中率);NULL 值列表(1空0不空);记录头信息(delete_mask标识数据是否被删除、next_record下条记录位置、record_type当前记录类型,0普通记录1B+树非叶子节点记录2最小记录3最大记录)

「记录的真实数据」:定义字段+隐藏字段(row_id隐藏字段6byte,建表时指定主键或唯一约束列就没有、trx_id事务id 6byte、roll_pointer这条记录上个版本指针 7byte)

MySQL的NULL值怎么存放

NULL 值不会存储在行格式中真实数据部分,MySQL 的 Compact 行格式会用「NULL值列表」来标记值为 NULL 的列。NULL值列表占 1 字节,当表中所有字段都定义成 NOT NULL就不会有 NULL值列表,可节省 1 字节空间

MySQL怎么知道 varchar(n) 实际占用数据大小

Compact 行格式中的「变长字段长度列表」

行溢出后MySQL怎么处理

InnoDB会自动将溢出数据存到「溢出页」中,然后真实数据处用20 字节存储指向溢出页的地址,从而可找到剩余数据所在的页