2020-10-28

InnoDB引擎如何存储记录

一、InnoDB数据页:
InnoDB引擎将数据(记录)划分为若干个页,以页作为磁盘和内存之间交互的基本单位,一般页大小为16KB(可以手动设置为8KB、32KB等),也就意味着一次IO操作至少读取16KB数据(这样就不用一条条记录的读取了)。下图是InnoDB数据页的结构示意图:

    注意1:页新建时User Record是不存在的,只有当插入一条记录后,由Free Space分配空间给它。
    
    注意2:MySQL规定一个页至少有两行记录,每个页都需要136B大小空间存储元数据信息。
    
    注意3:页内物理地址连续。

在这里插入图片描述参考链接:
https://www.cnblogs.com/joeysh/archive/2019/04/16/10720192.html

二、InnoDB行格式类型Row_Format:
MySQL的InnoDB引擎支持四种行格式:Compact、Redundant、Dynamic、Compressed。

show table status ;查看表的信息,包含引擎类型、行格式等等
  CREATE TABLE u1(
	 uid int,
     uname VARCHAR(10),
	 PRIMARY KEY(uid)
)ROW_FORMAT=COMPACT;创建表时指定行格式,MySql5.7之后默认是Dynamic行格式了

三、Compact行格式记录的内容:
一条记录包含两大部分:记录的额外信息extra information和记录的真实数据(隐藏列和真实列)。
在这里插入图片描述

一)、额外信息:
1、变长字段长度列表:MySQL支持的变长数据类型有varchar、text、blob等。对于定长数据类型比如char(10),只要不超过10个字节,都按照10字节存储;而变长varchar(10),存储两部分:一是真正的数据、二是它的长度(字节数大小)。故变长字段长度列表逆序存储那些变长字段的长度大小。

2、Null值长度列表:创建表时没有显示定义该列为Not Null的字段都有可能为空。故Null值列表用整数个字节长度的二进制位来标志列是否为空,如果有多列数据空,则逆序标记。如下图:一条记录中有三列c1、c3、c4空。
在这里插入图片描述

3、记录头信息:固定5B大小。
在这里插入图片描述

delete_mask:表示该记录是否删除了
n_owned:当前槽slot管理的记录数(下一节页内记录如何存储)
heap_no:当前记录在页中的物理地址
record_type:记录类型,0表示普通用户记录、1表示目录项记录(即B+树非叶子结点记录)
next_record:按主键递增顺序指向下一条记录,是逻辑地址

二)、记录的真实数据:
当插入一条记录时,MySQL会自动为每个记录加一些隐藏列
row_id:行ID,6B大小,一条记录的唯一标识(主键),非必须;
transaction_id:事务ID,6B大小,必须存在;
roll_pointer:回滚指针,7B大小,必须存在。
【因为InnoDB支持事务】

四、页内多条记录如何存储?记录头信息+页目录+单链表
利用记录头信息的next_record指针指向逻辑上(主键递增顺序)的下一条记录,就这样所有记录会形成一条单链表!而且我们知道单链表特别适合增删记录。

But,表最多的操作是查询啊,单链表查询效率O(n),太慢了!再次利用数据页结构的page Directory页目录将所有记录分组(槽slot)。

补充:InnoDB规定最小记录所在槽的n_owned=1;中间分组n_owned∈[4,8];最大记录分组的n_woned∈[1,8]。
在这里插入图片描述
这样当查询记录时,不需要遍历整个单链表了。先对页目录二分查找找到对应的槽slot,再对槽内记录遍历即可。

五、页间多条记录如何存储?
随着插入记录增多超过16KB大小时,会新增数据页,那么这么多的页是如何组织的? 双链表+File Header
File_Header里面有File_Page_Prev指向上一页、File_Page_Next指向下一页。在这里插入图片描述参考链接(这个最全):https://blog.csdn.net/weixin_41862308/article/details/106736203

总结:多个数据页间组成一个双链表、而每页内记录组成一个单链表。
同时每页会为页内记录生成一个目录项。在根据主键查找时,会先二分
查找页目录,再遍历槽内记录。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值