Mysql--InnoDB记录存储结构

具体细节 请去掘金购买《MySQL 是怎样运行的:从根儿上理解 MySQL》

InnoDB页简介

  • 1.innodb把数据按照页为基本单位作为与磁盘的交互单位。
  • 2.页大小一般为16KB

InnoDB行格式

  • 1.记录是以行格式或者记录格式存储在磁盘
  • 2.compact,redundant,dynamic和compressed等四只格式

指定行格式的语法

mysql> CREATE TABLE record_format_demo (
    ->     c1 VARCHAR(10),
    ->     c2 VARCHAR(10) NOT NULL,
    ->     c3 CHAR(10),
    ->     c4 VARCHAR(10)
    -> ) CHARSET=ascii ROW_FORMAT=`COMPACT`;
Query OK, 0 rows affected (0.03 sec)

COMPACT行格式

  • 1.主要是两部分:记录的额外信息和记录的真实数据。
  • 2.额外信息:变长字段长度列表,NULL值列表,记录头信息
  • 3.真实数据:各个列的值。

变长字段长度列表

  • 1.VARCHAR(M)、VARBINARY(M)、各种TEXT类型,各种BLOB类型.
  • 2.对于变长的字段,mysql存储其真实数据内容和占用的字节数。
  • 3.Compact行格式中,所有变长字段的占用的字节长度放在开头形成链表,是逆序存放(比如列a,列b,则链表就是ba)
  • 4.如果该可变字段允许存储的最大字节数(M×W)超过255字节并且真实存储的字节数(L)超过127字节,则使用2个字节,否则使用1个字节。
  • 5.该字节的第一个二进制位作为标志位:如果该字节的第一个位为0,那该字节就是一个单独的字段长度(使用一个字节表示不大于127的二进制的第一个位都为0),如果该字节的第一个位为1,那该字节就是半个字段长度。
  • 6.变长字段长度列表中只存储值为 非NULL 的列内容占用的长度,值为 NULL 的列的长度是不储存的

NULL值列表

  • 1.把列中的存储NULL的都放入列表中,这样就不需要再真实数据中占有地方
  • 2.如果所有列都没有允许存储NULL 则NULL值列表不存在。
  • 3.将允许存储NULL的列表采用二进制位表示,0表示该列值不为NULL,1则是NULL。注意是逆序。
  • 4.规定了列表表示的二进制必须是整数个字节,如果NULL值列不够8则 高位设置为0补齐。

记录头信息

  • 1.由固定的5个字节组成,40个位可以表示40个不同的意思

记录的真实数据

  • 1.除了正常的列信息之外,还会包含一些隐藏列
  • 2.row_Id(如果不存在主键或者其他的唯一索引,则有该列)
  • 3.tracsaction_id(事务id)
  • 4.roll_pointer,指向了历史记录,可以帮助回滚和实现MVCC

CHAR(M)列的存储格式

  • 1.当char列采用的是定长字符集时候,该列占用的字节数不会被加到变长字段长度列表,否则会加入
  • 2.比如采用了ascii就不需要加入,采用UTF-8就需要加入
  • 3.变长字符集的CHAR(M)类型的列要求至少占用M个字节,比如我们采用UTF-8编码CHAR(10),那么字节长度可能为10-30,所以我们存入空字符也会占用10个字节
  • 4.上述的好处是如果记录更新,可以直接利用该存储空间,无需重新分配。(当然如果如果更新记录超过10个字节还是需要重新开辟)

注意了在Compact行格式下,Mysql的列有变长类型,同时对列的编码字符集也有动态的,只有是定长类型的列并且也采用定长类型的编码列,占用分配空间大小才固定。

Redundant行格式

  • 1.主要是两部分:记录的额外信息和记录的真实数据。
  • 2.额外信息:字段长度偏移列表,记录头信息
  • 3.记录的真是数据。

字段长度偏移列表

  • 1.记录所有字段包含隐藏列的长度信息,逆序。

记录头信息

  • 1.Redundant行格式多了n_field和1byte_offs_flag这两个属性。
  • 2.Redundant行格式没有record_type这个属性。
  • 3.1byte_offs_flag:标记字段长度偏移列表中每个列对应的偏移量是使用1字节还是2字节表示的
  • 4.1byte_offs_flag的值是怎么选择的:根据该条Redundant行格式记录的真实数据占用的总大小来判断的:当记录的真实数据占用的字节数不大于127(十六进制0x7F,二进制01111111)时,每个列对应的偏移量占用1个字节
    ,当记录的真实数据占用的字节数大于127,但不大于32767(十六进制0x7FFF,二进制0111111111111111)时,每个列对应的偏移量占用2个字节。
    大于32767的情况存放到了溢出页中
  • 5.在Redundant行格式下 多余字节存放溢出页,在本页只保留前768个字节和20个字节的溢出页面地址,因此只需要2个字节记录偏移量

Redundant行格式中NULL值的处理

  • 1.因为Redundant行格式并没有NULL值列表
    1. 将列对应的偏移量值的第一个比特位作为是否为NULL的依据,该比特位也可以被称之为NULL比特位
  • 3.正是因为首位被做Null比特位了所以才在大于127的时候使用2个字节来记录长度
  • 4.如果NULL列采用定长字符集来存储,则采用0x00字节填充,如果是变长则不占用任何存储空间

CHAR(M)列的存储格式

  • 1.Compact行格式在CHAR(M)类型的列中存储数据的时候还挺麻烦,分变长字符集和定长字符集的情况
  • 2.而在Redundant行格式中十分干脆,不管该列使用的字符集是啥,只要是使用CHAR(M)类型,占用的真实数据空间就是该字符集表示一个字符最多需要的字节数和M的乘积
  • 3.因此不会产生碎片

行溢出数据

  • 1.除了BLOB或者TEXT类型的列之外,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节
  • 2.这个65535个字节除了列本身的数据之外,还包括一些其他的数据(storage overhead),比如说我们为了存储一个VARCHAR(M)类型的列,其实需要占用3部分存储空间:
    真实数据
    真实数据占用字节的长度
    NULL值标识,如果该列有NOT NULL属性则可以没有这部分存储空间
  • 3.如果该VARCHAR类型的列没有NOT NULL属性,那最多只能存储65532个字节的数据
  • 4.Compact和Reduntant行格式中,对于占用存储空间非常大的列,在记录的真实数据处只会存储该列的一部分数据
  • 5.记录的真实数据处用20个字节存储指向这些页的地址,这些也采用链表进行连接。
  • 6.不只是 VARCHAR(M) 类型的列,其他的 TEXT、BLOB 类型的列在存储数据非常多的时候也会发生行溢出。

行溢出的临界点

  • 1.MySQL中规定一个页中至少存放两行记录

Dynamic(5.7默认)和Compressed行格式

  • 1.Dynamic和compact很相似,处理行溢出数据时有点儿分歧,只记录地址,不会记录部分真实数据。
  • 2.Compressed行格式和Dynamic不同的一点是Compressed行格式会采用压缩算法对页面进行压缩,以节省空间。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容