表
2018-11-28 本文已影响8人
简书徐小耳
索引组织表
- 在innodb中,表都是根据注解顺序组织存放的,这被称为索引组织表。
- 每个表都会有一个主键,如果没有主键则会先查看是否有非空的唯一索引,如果有则是主键否则innodb会自己创建一个6字节大小的字节
innodb逻辑存储结构
- 所有数据被
逻辑
的存放在表空间 -
表空间由段,区,页(块)组成
image.png
表空间
- 如果启用了innodb_file_per_table,则每个表的字节表空间只存放数据,索引,和插入缓冲bitmap页,其他的如undo,插入缓冲索引页,double write buffer系统事务还是存在共享的表空间
- innodb 不会回收表空间
段
- 数据段,索引段,回滚段。因为数据是按照索引组织的所以数据即索引,索引即数据。 所以索引段就是b+数的非叶子节点,数据段就是b+树的叶子节点。
区
- 区是由连续的页组成的,任何情况下每个区的大小都为1MB。
- 为保证区中页的连续性,innodb一次性从磁盘申请4~5个页
- 默认情况下innodb的页大小为16KB,即一个区一共有64个连续的页
- 还有压缩页,即通过KEY_BLOCK_SIZE 设置为2K,4K,8k。因此每个区对应页的数量优势分别为512,256,128
- 也可以通过innodb_page_size 设置页的大小为4k,或者8K(不是压缩,原先16k),但是区的大小不变。
- 我们设置innodb_file_per_table,创建的表大小默认是32个页大小的碎片页来存放数据,等到这些用完,在申请64个连续页
页(块)
- 页是innodb磁盘管理的最小单位
- 页可以压缩也可以设置大小
- 页的类型有数据页,undo页,系统页,事务数据页,插入缓冲位图页,插入缓冲空闲列表页,未压缩的二进制大对象页
行
- innodb是面向列的,每个页最多允许存放16KB/2-200行记录
innodb行记录格式
image.png
- compact:存储记录
- 根据列的长度大小,其首部变长字段分别可以使用1个或者2个字节表示
- null 表示该行数据是否有null
-
头信息固定为5个字节40位,其具体信息如下
image.png - total代表的实际存储每个列的数据,如果是null 则不会占用空间,只是在null标识增加
- 还有事务ID列和回滚指针列 分别为6字节和7字节的大小
- redundant:存储记录
- 首字段跟compact一致
- image.png
-
头信息占用了6个字节 48位
image.png
- 行溢出数据
- innodb 可以将一条记录中的某些数据存储在真正的数据页面之外,不一定是BLOB,LOB大对象类型的数据,varchar也有可能 ,主要是根据数据内容的真实大小。其会保留768个前缀字节,剩余直接放入到off page
- compressed和dynamic行记录格式
- 以前的compact和redundant成为antelope文件格式,新的文件格式称为barracuda,其包含compressed和dynamic。
-
其对行溢出 ,则将所有字节都存放到off page,原来的数据页只存放20个字节的指针
image.png - compressed 还可以对存储在其中的行数据以zlib算法进行压缩,因此可以对于大对象 blob ,text ,varchar 可以有效的存储
-char 的行结构存储
- 多字节字符集的情况下,char和varchar的实际存储基本是没有区别
innodb数据页结构
首先发张图
image.png
- 页是innodb存储引擎管理数据库的最小磁盘单位,页类型为B-tree node的页存放的即时表中行的实际数据
file header,page header,file trailer 用来标记下该页的一些信息,如checkSum,数据页所在B+树索引的层数所以大小是固定的,而userecords,free space,page directory 是实际的行记录和存储空间 所以大小是动态的
- file header
-
大小固定为38字节
image.png
image.png
- page header
- 大小固定为56字节
- 用来记录数据页的状态信息
-
记录在页中是按照堆的形式成分
image.png
image.png
- infimun 和supremum records
- 每个数据页都有两个虚拟的行记录,用来限定记录的边界
- infimum记录是比该页中任何主键值都小的值,反之supremum 则是最大的值,在页创建的时候被建立,无法删除
- user records(用户记录,即行记录)
- 实际存储行记录的内容
- free space
- 空闲的空间,也是一个链表数据结构,在一条记录被删除后,该空间会加入到该空闲链表
- page directory
- 存放的是记录的相对位置,而不是偏移量
- 我们恶意称这些记录指针为slots或者directory slots
- slots 不是每个记录都有,其是一个稀疏目录,一个slot 可能包含多个记录
- infimum的n_owned 值总是1,supremum的n_owned 为[1,8],其他用户记录的范围是[4,8]
- 当记录被插入或者删除的时候需要对slot 进行分裂或者平衡的维护操作。
- slot中的记录按照索引键值顺序存放,这样可以利用二叉查找迅速找到记录的指针
- b+树索引本身并不能找到具体的记录,只能找到该记录所在的页,然后数据库把页载入到内存,再通过page directory 在进行二分查找。
- file trailer
- 检查页是否已经完整地写入磁盘,所以设置了file trailer
- 利用fil_page_end_lsn 占8个字节,前四个代表该页的checksum值,最后四个字节和file header的 fil_page_lsn相同,这两个部分分别和file header的 fil_page_space_or_cheksum以及fil_page_lsn进行比较 如果不一样则页不完整
- 大小固定为8字节
Named File Formats机制
- 解决不同版本的页之间兼容的问题
-
老版本称为 antelope 新版本称为 barracuda具体如下
image.png
分区表
- 是由mysql完成的而不是引擎完成
- 分区的过程是将一个表或索引分解为多个更小,更可管理的部分
- 逻辑上只有一个表,但是物理上这个表或索引可能由数十个物理分区组成
-每个分区都是独立的对象 - 只支持水平分区,指的是将同一个表中的不同行记录分配到不同的物理文件
- 垂直分区:按照列分区10个字段 55分开
- range 分区,list 分区,hash分区,key分区,cloumns分区,前面都是4个分区都是整型(或者使用函数变为整型)
- null值分区会被视为小于任何一个非Null值
- OLTP 在线事务处理,OLAP在线分析处理