MySQL -- 行格式

前言

最近在学MySQL,决定记录一下,能写多少写多少,不定时更新,加油。

正文

分几个部分来吧,大致如下:

  • 字符集与比较规则

  • 行格式与数据页

  • InnoDB索引

  • 访问方法与连接

  • explain 与 子查询优化

  • redoundo 日志

  • MVCC 与 锁

本文为第二部分 第一节 行格式


概述

一拍键盘,上回说到:

  • MySQL分客户端与服务器两大块
  • 数据都是存储在服务端的,由存储引擎把控这部分
  • 存储引擎分为InnoDB MyISAM Memory等等

上回说没说到不重要, 重要的是


先对InnoDB有个大致的了解,

  • MySQL中的记录都存储在页中
  • 每页默认大小16KB
  • InnoDB中定义了很多类型的页:存储数据的叫数据页(InnoDB中也叫索引页)、存放段的INODE页、存放undo日志的undo日志页、表空间前多少个特殊作用的页等等

下面基于InnoDB看看MySQL中数据是如何存储的.


行格式

定义

  • 库中记录展示时是一条记录一条记录的,也就是一行一行
  • 那这样的每条记录在库中的存储方式称为行格式
  • 行格式归属于存储引擎范围(换个存储引擎可能就不同方式存储)

分类

  • Compact
  • Redundant
  • Dynamic
  • Compressed

下面通过Compact行格式的实现来初步看看MySQL的记录存储智慧。

正文

本节内容均是单条记录范围内, 不要绕晕, 下一章讲页就是页范围

Compact行格式各部分组成(来源网络)

一、变长字段长度列表

几个点了解一下:

  1. 何谓变长?就是不定长。不定长从两个点理解: 字符集与属性类型
  2. 变长类型示例:varcharvarbinarytextblob
  3. 这些变长列的实际占用字节数以逆序方式存储在变长字段长度列表
  4. 允许的最大字节超过255且实际存储超过127字节, 使用两个字节存储其长度, 否则使用一个字节.(看到有多节省了吗...)
  5. 变长列不为null时, InnoDB才会存储其字节长度
  6. 如果没有变长列或变长列都为null,则当前记录没有此部分
  7. 第一个字节的第一位是标志位,表示是否双字节表示.(有点像gbk哈)

这里注意最后一点, InnoDB在读字段变长列表时会先查表结构, 允许的最大字节数超过255时才会使用这个二进制位作为标识位来判断是读一个字节还是两个字节,没有超过就直接读一个字节也就不存在标识位了

举个栗子
col 类型为varchar(255)

  1. 如果字符集为ascii, col列允许的最大字节为 255 * 1 = 255个字节,说明撑死了2^8 - 1个字节,一个字节存其长度就够了;
  2. 如果字符集为utf8, col 允许的最大字节为 255 * 3 = 765个字节,大于255,那就要看实际占用字节数了, 一个不够就两个

问题:Compact行格式下,页中某列最大字节长度是多少?(可以先想想)

答案:不要忘了记录是存在页里面的,每页一般16KB,也就是65536个字节,16次方不就占两个字节吗~
当然有可能一列超过16KB,那就会溢出了(溢出页),这里只记录当前页的占用字节数。

二、NULL值列表

同样几个点了解一下:

  • 主键列、not null 修饰的列不在此范围内
  • 如果没有可以省略此部分。(即除了主键列全是not null修饰)
  • 一个列一个二进制位,1表示null
  • 同样逆序存放
  • 此部分由整数个字节组成, 不足地方高位补0

这就不举栗子了,被我吃完了。

三、记录头信息

记录头:"上面的两位都是弟弟。"

Compact行格式下记录头各部分示意图(来源网络)
名称 大小(单位:bit) 描述
预留位1 1 没有使用
预留位2 1 没有使用
delete_mask 1 标记该记录是否被删除
min_rec_mask 1 B+树的每层非叶子节点中的最小记录都会添加该标记
n_owned 4 表示当前记录拥有的记录数
heap_no 13 表示当前记录在记录堆的位置信息
record_type 3 表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录
next_record 16 表示下一条记录的相对位置

这里一堆属性,我们挑几个看看

delete_mask
  • 被删除的记录值为1, 正常记录为0
  • delete 语句后的记录不会被立刻删除,而是将这条记录的delete_mask置1, 称为delete mask操作,与真正的直接删除要区分开(update不更新主键且不能就地更新时直接删除,也就是改完delete_mask后直接加入到垃圾链表中),这种操作是因为MySQL还有一个东东叫MVCC,后面会讲。
  • 这个属性还涉及垃圾链表、重用空间什么的
min_rec_mask
  • 这个属性目前我也不知道是干啥的,哪位大佬知道的可以告诉我一声~
n_owned
  • 在页面内为了快速搜索(二分查找)会分组
  • 只有组内最大记录此字段有值,记录组内记录数,除了最小记录,大小一般在4-8区间
heap_no
  • 后面我们会说到记录在页面内其实会组成一个单链表,从头到尾,此属性依次增加.
  • 最小记录为0,最大记录为1,真正记录的这个值从2开始
record_type
  • 页内记录类型,目前有四种类型
  • 0就是我们的一般意义上的记录,1是索引用到的,后面再说
  • 2是最小记录、3 是最大记录
next_record
  • 本记录的真正数据到下一条记录的真正数据的偏移量(可以当做存了个指针,向后是额外信息,向前是具体的列)
  • 根据这个属性,页面内所有记录都串了一个单链表
  • 单链表按主键排序,从小到大,最小记录与最大记录分别为头结点和尾节点

四、正式数据部分

额外信息部分说差不多了,到真正存储数据的地方了,喝口水再继续吧。


朋友之上恋人未满的三个特殊列:

列名 是否必须 占用空间 描述
row_id 6字节 行ID,唯一标识一条记录
transaction_id 6字节 事务ID
roll_pointer 7字节 回滚指针
这三个的位置在真正数据的最开始位置, 属于MySQL为我们添加的隐藏列,不过也不是所有的情况都添加:
  • 表中没有指定主键且没有Unique列, MySQL会为我们添加一个row_id 作为主键

  • 其他两个每条记录都会默认添加

  • trx_id 其实就是事务ID,这个是在五号表空间的全局变量

  • roll_pointer 回滚指针,指向一条undo日志记录(在undo日志记录页中)

  • MySQL有个自增的功能,其实是维护了一个全局变量
  • 这个变量存储在系统表空间的7号表(7号表空间)中,随着记录的插入而自增, 每逢256的倍数就刷到磁盘中
  • 重启系统取出后加上256再赋予给自增列, 因为库中可能已经超过了刷到磁盘中的这个值
  • 最后一点, 强扭的瓜不仅不甜也不解渴, 所以没看懂就不要勉强......

到此, 每条记录的Compact格式说完了,其他行格式大家有兴趣就自己找找资料看看吧,这里不展开了。


数据页放下一章,太长了也不好,我说的对吧

回见~

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

推荐阅读更多精彩内容