1.InnoDB的行内格式
InnoDB 是基于磁盘的的存储引擎 ,在读取数据都是先读取到内存上,然后在 显示出来,innoDB会一页为单位,最少将16kb的数据和内存作为交换读取到内存展示,或者说最少把innoDB最少16kb内容写到磁盘中。
InnoDb现在已经设计4种行级别格式,分别是Compact.Redundant.Dynamic.Compressed 四种格式
1.第一种 Compact类型的格式
我们创建一个建立表中在语句结尾 在 ROW_FORMAT=COMPAT 中,我们在表假如插入一条语句 insert into a(a) values (‘1’) ,(null)
表中间记录真实的值和 一些额外的数据 比如一些变长字段,和null值列表,和记录头信息,字段得边长信息是通过 字段边长得内容逆序排放 , 然后通过假如这个字符是‘A’,通过一个这一列得最长最多使用得字节数为a , 这个是utf_8的就是 这个字符就是 3 就是 a3 ,假如 a3小于255 就有一个字节去存储额外的记录长度 ,假如 这个 a*3大于255 并且是 实际占用字节数据 超过127 就用两个 字节表示真正占用字节数,(但是有一些超长字符,本身就是超过了 16K 就用两个字节是记录 它 的长度, 还有就是记录null值列表第一种就是记录的nill值列表就是通过 二进制一个字节 来记录 ,是通过筛选出 不是 not null的列表 ,比如一个列有3个列 的空值,那么就会有3个列的记录它的倒数排列 。不足一个字节高位补零,还有就是 记录的头信息 ,比如我们头信息是由5个固定字节组成 也就是 5个 头信息 ,40个二进制位组成,一般 两个 预留位和 标记记录是不是被删除,B+树的每层非叶子节点的最小记录添加标记,还有当时记录拥有的记录数,表示当前在记录堆的中的数据 ,还有当前的记录类型。还表示当前记录下一个节点相对位置 ,还有就是 记录的真实数据 ,可以看的见的列 和看不见默认的隐藏列 ,分别是 唯一标识,事务id,回滚指针, 分别是占用 667个字节 ,一般 正常情况下 ,innodb会选取 我们 当前指定的 主键作为主键,但是 如果没有选取的 ,就会选取 当前列中唯一键作为 唯一主键,假如都没有innoDb 就会选取一个隐藏主键, 还有 行溢出数据,varchar(M)类型 最多是占65535个字节 ,我们一列 包括头信息和 假如还有 null信息的 那么一个字节最多占用65532个字节 ,null占一个字节 ,大于 127个字节长度占用两个字节,假如是notnull的 那么是65533个字节 ,假如我们数据库或者表中选择的字符集是ascii的字符集 ,那么 varchar最大是 (65535),假如使用时别的字符集就应该另算了 ,我之前说过 InnDB每次指读取 16k字节的数据去读或者写,假如这种超大数据是处理的?其实对于这种超大数据是innoDB在存储的时候,会把存储的数据在字符串前769个字节纯在本地,其他会花20个字节指向存储的地址 ,超出来的部分就会被称为溢出页,那么溢出或者不溢出的临界值就是8098个字节,
2.Redundant
过于古老 mysql 5.0 之前的 现在基本 不用 只有偏移头信息和记录头信息
3.daynamic和Compressed行格式
daynamic和Compact格式很像就是 区别就在于他会不会记录行溢出的数据 并且daynamic是5.7默认格式, Compressed和其他不同的是他会用压缩算法,
2.InnoDB数据页简介
1.inndb的数据页分为7个部分 file header ,Page header ,infimum +supremum ,user Records ,free Records Free Space Page Dicectory fileTailer
假如我们每一次在想创建一条数据的时候就会free Records 向 user Records 扩展一份数据,知道free Records被 UserRecords 占满了数据,这个时候就必须要要新开一份数据页, 每一列的信息头信息有预留位 和delete_mark 这个代表这一条数据是不是被删除,那么这个一条数据是假如被我们delete掉了 是真的被删除了吗?其实不然,只是把delete_mark的 0变成了 1,为什么他不是及时删除,因为每次删除都要重新排序,消耗性能,这个数据会重新组成链表,就是被成为垃圾链表,链表这个空间 也就是成为可重用空间,那么这个可重用空间就是在用在新的记录在插入这个表中的时候,这个时候这个可重用空间就是被覆盖掉 ,信息头信息里面还有min_rec_mask,b+数的每层非叶子节点种最小记录都是会添加这个标记 ,heap_no是表示本条数据在当前表中的位置,record_type 表示当时记录的类型,next_record 表示当前头信息记录相对位置,为什么说是相对位置,因为,它们在记录信息头中是按照头信息是排列的,那么本是是一种链表接口 只想下一条的位置,因为在头信息中Supremum就是最大记录然后infimum就是最小记录,中间就是处于一种链表结构,就是那种指向了下一条数据的结构,进行的排序,假如我们用这个用delete语句是删掉一条数据,那么 这个时候这个链表的指针会直接只想下一条数据,假如不会真删除,假如你先先表插入了一条记录 ,这个时候 ,新的数据就会直接插入原有的位置 ,
总的来说 多条数据组成一页 16K的目录 然后它们前面的 长短大小值会 通过头信息组成一个 链表 ,通过记录的信息头的 next_rerords来进行排序 ,加载进内存中间里面来,
page Directory 页目录 因为在 会在一个页会新增一个很多槽 这些槽会在相当书本的目录,正常情况下,它在找一个目录的时候会通常会先把二分法查找,然后找到两个槽的位置进行比较,然后进行,细微的比对,