主键三连
- 显示定义主键。
- 如果没有显示指定,查找表中唯一索引,如果有,该列为主键。
- 不符合上面两条,InnoDB自动创建一个6字节大小的指针。
逻辑存储结构
- 表空间->段->区->页
表空间
每张表的表空间存放的只是数据、索引、插入缓冲。其他类型的数据,如undo信息,系统事务信息,二次写缓冲等还是存放在共享表空间中。
段
每个段开始时,先用32个页大小的碎片页来存放数据,用完后在用区(64个连续页)
- 数据段 B+数的叶子节点
- 索引段 B+数的非叶子节点
- 回滚段
区
由64个连续的页组成,每个页16KB,每个区1MB。
InnoDB每次最多可以申请4个区,以此保证数据的顺序性能。
页
每个页至少2行,最多7992行
- 数据页(B-tree Node)
- undo页
- 系统页
- 事务数据页
- 插入缓冲位图页
- 插入缓冲空闲列表页
- 未压缩的二进制大对象(BLOB)页
- 压缩的二进制大对象页
行
每个页存放16KB/2~200行记录,即7992行。
物理存储结构
- 共享表空间
- Redo文件组
- 表结构定义文件
- 独立表空间(需要设置才有)
InnoDB行记录格式
- Compact行格式
变长字段
逆序放置
列长小于255,用一个字节;大于255,用两个字节;最大不能超过2个字节。所以varchar最大长度是65535。
NULL标志(至少一个字节)
逆序放置
记录头信息
固定占用5字节
隐藏列——事务ID和回滚指针列
RowID列(6字节)
行溢出数据
InnoDB存储引擎可以将一条记录中的某些数据存储在真正的数据页之外,即作为行溢出数据。
Char的行结构存储
在多字节字符型的存储中,char被视为变长类型,未能占满长度的字符用0x20填充。可以说在多字节字符集的情况下,char和varchar的行存储基本没有区别。
InnoDB数据页结构
InnoDB数据页由7个部分组成:
文件头 file header
大小固定 8个部分,共38个字节
属于哪个表空间
上一页、下一页(叶子节点双向链表)
页类型(叶子节点、索引节点、undo log页···)
等···
页头 page header
大小固定 14个部分,共56个字节
记录数量
空闲链表首指针
堆中第一条记录的指针
属于哪个索引ID
等···
Infimun + supermum records
每页中有两个虚拟行记录,用来限定记录的边界。
Infimun 最小值
supermum 最大值
用户记录(行记录) user records
空闲空间 free space
链表数据结构,有记录被删除后,会被加入到空闲链表中。
页目录 page directory
存放记录的相对位置
B+数索引只能找到记录所在的页,数据库把页载入内存,然后通过page directory进行二分查找。二分查找的时间复杂度很低,通常忽略这部分时间。
文件尾信息 file tailer
页的完整性保证
大小固定 1个部分,共8个字节
约束
数据完整性
实体完整性
域完整性
参照完整性
四种约束
主键
唯一键
外键
default
not null