字节二面说说InnoDB行记录存储结构
前言
我们平时在向MySQL数据库表中插入数据时,实际数据是以行记录的格式存储在磁盘上的,本篇我们就一起来详细地了解下MySQL的行记录格式,理解了行记录的格式有助于我们后面了解MySQL如何快速在页中定位出行记录,以及MySQL的版本控制链,事务隔离级别等等,行记录格式是许多MySQL核心知识的基础。 InnoDB行记录类型
MySQL中总共提供了四种类型的行格式: Compact ,Redundant ,Dynamic ,Compressed 。
在创建表或修改表的时候可以指定行记录的格式 create table 表名 row_format=行格式名 alter table 表名 row_format=行格式名
知道就行,不需要去记住,基本上使用不到 Compact行格式
在四种类型的行格式中,我们主要来学习 Compact 格式,其他格式的行记录类似;
从图中我们可以看出行记录主要是由4部分组成:变长字段长度、Null值列表,行记录头信息以及列的真实数据 变长字段长度列表
在MySQL中很一些变长的数据类型(varchar,text等),MySQL需要知道这些数据的实际长度,这样才能正确的在真实数据中取出对应列的数据,所以变长字段是由两部分组成: 真实数据的长度 真实数据的字节
每个变长字段的长度要么用1字节要么用2字节表示,由此就决定了每个字段的最大字节数是65535; 假如字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766; 假如字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。
那到底什么时候选用1字节什么时候选用2字节呢?
这里需要定义三个变量:w,m,l 假如使用的字符集是utf8mb4,每个字符占用的字节数是4字节,那么w=4;假如字符类型若为utf8,每个字符最多占3个字节,那么w=3; 所以w表示字符集中每个字符所占的字节数 varchr(m),这里m表示的是定义的字符的长度 l 表示的是该字段真实数据占用的字节数
当 m*w <= 255 ;表示该字段定义的最大长度都不会超过1字节,那么该字段的长度就用1字节表示
当 m*w > 255 && l<=127 ; 表示该字段定义的长度可能会超过1个字节,但是当前的实际长度是小于127的,可以用1个字节表示
当 m*w > 255 && l>127 ; 用2字节来表示该字段的长度
思考:为什么与l比较的值是127呢? 当我们定义的变长字段可能大于255(也就是超过一个字节)时,MySQL如何才能知道当前读取的字节该字段的完成字段长度,还是该字段的半个字段长度,为了解决这个问题,MySQL使用了1字节的首位,当首位为0表示当前是1字节,当首位为0表示当前长度是2字节;由于占用了1字节的首位,所以剩下7位所能表示的最大值是127
变长字段不会存储为Null列的长度;其次并不是行记录中一定需要变长字段长度这段内容,如果行记录中没有定义变长字段或者是变长字段都为Null,那么就不会有变长字段长度这部分
变长字段占用的字节数按照顺序逆序存储 Null值列表
一条记录中某些列通常可能允许为null,所以Compact行格式把这些允许为null的进行了统一管理; 首先统计出表中定义的哪些列允许为null 如果表中的字段都不能为空,那么就不存在null值列表;如果存在允许为null的字段,那么就按照字段的顺序为每个字段对应一个二进制位,当二进制位为1时表示该列值为空;当二进制位为0时表示该列值不为空 Null值列表必须有整数个字节来表示,所以对应没有占用的位使用0补位
行记录的头信息
头信息中主要包含了6个字段,其中5个字段也是在面试中经常被问到的,为了方便记忆,我们把5个字段对应到手的5根指头: n_owned(拇指): 一个数据页会被分成很多个组,每组最后的一条记录该字段为1,其他记录该字段为0,就像分组中所有的记录的大哥;(对应拇指) deleted_flag(食指): 标记该记录是被删除的;当记录被删除时不会真实删除,而是用该字段标记,并且把所有删除的记录使用链表连接起来,以后的文章会继续说到这个字段。(想象下你平时挖鼻屎是不是用的食指) heap_no(中指): 表示当前记录在数据页中的相对位置(MySQL使用该字段来表示记录位置,可以和中指对应,不可描述) record_type(无名指): 表示当前记录属于哪种类型,(无名指用来带戒指的,与分类有关,可以把人分为已婚和未婚,) 0表示普通记录1表示目录项记录,索引中非叶子结点中的数据记录都是12表示infrmum记录,每个数据页中至少会有两条记录,其中最小记录的record_type=23表示Supremum记录,每个数据页中至少会有两条记录,其中最大记录的record_type=3 next_record(小拇指): 存放下一条记录的相对位置(当数数时,左手的小拇指数完之后就该换右手了,和next_record表达的意思类型)
最后一个字段min_rec_flag : B+树中每层非叶子结点最小目录项记录该字段为1;该字段相对于其他5个字段显得不那么重要,不会影响理解B+树索引 隐藏列
除了用户自定义的数据列以外,MySQL还会为每行记录生成3个隐藏列 row_id: 行ID,记录的唯一标识;当用户在表中定义了主键字段就优先选择用户定义的主键,如果没有,就查找是否有定义不为null的唯一索引,如果有就把该列作为主键,如果没有MySQL就会生成一列row_id隐藏列作为主键 trx_id: 事务的ID;该字段对于实现一致性视图和事务隔离级别至关重要,以后会详细说明 roll_pointer: 回滚指针,指向的是该记录的上一个版本号,MySQL的MVCC主要就是通过这个字段来实现的。 溢出列
MySQL中所有的行记录都会被存储在数据页中,每个数据页的大小是16KB,也就是16384个字节;在前面我们讲过变长字段的长度可以用两个字节来表示,所以列的最大长度可以是65535,当遇到这种极端情况时,一个数据页是存储不下这一条记录的。
Compact行格式针对这种情况的处理方式是在真实的数据处记录该列的一部分数据(768字节),其他多余的数据会存储到新的数据页中(溢出页),然后在该记录中使用20个字节存储这些数据页的地址
溢出页与溢出页之间使用的链表相连接 其他的行记录格式:
Redundant :MySQL5.0之前的格式,直接忽略
Dynamic ,Compressed 与Compact 很像,只是在溢出列的处理有些差异,他们只会在真实数据列中使用20个字节存储溢出页的地址面试题char(M)定义的字段,在变长字段的长度列表中会记录该字段的长度吗?
欢迎大家在评论区留言讨论 最后(点关注,不迷路)
文中或许会存在或多或少的不足、错误之处,有建议或者意见也非常欢迎大家在评论交流。
最后, 写作不易,请不要白嫖我哟 ,希望朋友们可以 点赞评论关注 三连,因为这些就是我分享的全部动力来源
最后把自己费了老大劲才整理好的一套电子书资料分享给大家,点赞并回复"资料"即可
终于,轮到QQ用户鄙视微信了不知从何时起,微信用户和QQ用户开始势不两立了。特别是咱公司有两个同事,一个是主QQ党的,另一个是微信党。每次两人传文件的时候,都要battle一下。这不,最近又吵起来了QQ党先是
春晚上消失的45辆车去了哪里?老婆是京东的忠实用户,去年基本上家里的所有家电手机还有日常用品都是在京东购买的,京东那边基本今天晚上下单,明天就派送过来了,很快很便捷,不知道你用没有用过京东,反正她是一直用,还是
PlosGenetics揭示新烟碱类和多杀菌素类等重要杀虫剂的分子靶标烟碱型乙酰胆碱受体(Nicotinicacetylcholinereceptors,nAChRs)是一种主要表达于昆虫中枢神经系统的五聚体配体门控阳离子通道,也是新烟碱类(neon
冲上苹果总榜第一的啫喱有点忙,半夜声明被黑了已报警,独家回应抄袭质疑2月11日12日,一款名不见经传的社交App啫喱冲上苹果总榜免费社交榜单第一,同时有关啫喱泄露啫喱抄袭等质疑在社交平台发酵。啫喱是一款熟人社交App,关键词包括元宇宙AI捏脸游戏化
星巴克那么吵,为什么还有人带着苹果电脑去那看书学习?因为咖啡店里适度的白噪音,更有利于提升专注力。比如磨豆子的咔咔声爵士风格背景音乐声店员和顾客的交谈声开门关门声碎冰机的噪声锅碗瓢盆碰撞声这些声音,你单拿出任何一项,稍微放大,都可能
2022年春节期间移动数据流量创新高同比增长21。7工业和信息化部网站消息,春节期间(2022年1月31日2月6日),节假期7天,移动互联网接入流量达到434。9万TB,与2021年春节7天相比增长21。7全国移动电话计费时长共计5
快递春节不打烊B面我都上班了,网点还不上班中新经纬2月12日电(付玉梅)说好的春节不打烊,结果发货了还不是卡在路上。10多天了,快递一动不动,送了个寂寞。即便是春节的战线已经结束了,但在社交平台上搜索快递春节不打烊,还是会
如何配置一台适合爸妈使用的台式电脑?给老人配置一台合适电脑需要注意以下几个方面可以承受的高性价比父母一般是给我们做儿女的付出的很多,而对他们自己也多数时候是精打细算的过日子,所以一般来说全新的话配置我个人推荐I391
入门4建立每天学习Web3的习惯刚刚找Web3。0行业的信息,不知道看什么。一般我来到星巴克学习的时候,首先是打开知识星球看84000里面有没有更新什么信息,今天打开发现没什么信息,我就在那里发呆想接下来干什么呢
数据库系列你想要的sql全都有plus目录详细sql数据准备一ddl(datadefinelanguage)数据定义语言1库管理1库的创建(create)2库的修改(alter)3库的删除(drop)2表管理1表的创建
这个春节,谁是游戏市场最大赢家?2022年春节档游戏最大赢家腾讯游戏从已公布的某数据平台公布的收入数据来看春节期间iOS收入Top25中,王者荣耀和平精英原神英雄联盟手游梦幻西游占据Top5,王者和平LOL手游3