type
status
date
slug
summary
tags
category
icon
password
UTF-8编码中 一个数字1个字节 一个单词1个字节 一个汉字:少数3字节,多数4字节
 

1.行【这里是InnoDB存储引擎的行格式,一行记录最大为65535字节】

数据库中的记录是按照来存储的!
Redundant、Compact、Dynamic、Compressed
重点介绍Compact行格式:
notion image
变长字段长度列表
里边存储的是变长字段的长度(一个变长字段,1或2字节来存储他的长度)
notion image
NULL值列表
存储每个字段的记录是否为null
notion image
记录头信息【列举了比较重要的】
  • delete_mask :标识此条数据是否被删除。从这里可以知道,我们执行 detele 删除记录的时候,并不会真正的删除记录,只是将这个记录的 delete_mask 标记为 1。
  • next_record:下一条记录的位置。从这里可以知道,记录与记录之间是通过链表组织的。在前面我也提到了,指向的是下一条记录的「记录头信息」和「真实数据」之间的位置,这样的好处是向左读就是记录头信息,向右读就是真实数据,比较方便。
  • record_type:表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录
row_id
如果我们建表的时候指定了主键或者唯一约束列,那么就没有 row_id 隐藏字段了。如果既没有指定主键,又没有唯一约束,那么 InnoDB 就会为记录添加 row_id 隐藏字段。row_id不是必需的,占用 6 个字节。
trx_id
事务id,表示这个数据是由哪个事务生成的。 trx_id是必需的,占用 6 个字节。
roll_pointer
这条记录上一个版本的指针。roll_pointer 是必需的,占用 7 个字节。
具体数据
  • 列1 值
  • 列2 值
 
 

2. 页【page 默认16KB连续空间】

  • 问题:数据库读取数据不是按行来读取的,一次读取就是一次IO只处理一行数据,效率太低。
  • 解决:所以InnoDB 的数据是按「页」为单位来读写的
  • 类型:数据页、undo日志页、溢出页等
 

3.区【extent 1MB连续空间:64个连续的页]

  • 问题:数据量太大时,相邻两个页的物理位置不连续,离太远,磁盘查询 会有大量随机IO【随机IO是非常慢的!因为会频繁的移动磁头】,
  • 解决:数据量大的时候,按区进行分配空间,让相邻的两个页的物理位置相邻,这样就可以使用顺序IO在范围查询(扫描叶子结点)的时候性能就很高。
 

4 段 【segment 段:数据段、索引段、回滚段】

一个段是由多个区组成的,一般有数据段、索引段、回滚段等
  • 索引段:存放 B + 树的非叶子节点的区的集合;
  • 数据段:存放 B + 树的叶子节点的区的集合;
  • 回滚段:存放的是回滚数据的区的集合,之前讲事务隔离 (opens new window)的时候就介绍到了 MVCC 利用了回滚段实现了多版本查询数据。
 
notion image
 
 
 

补充:

1 行溢出怎么办?

Compact行格式处理方式:存储部分数据、20字节存储溢出页的地址:
notion image
 

2 顺序IO和随机IO?

notion image
notion image
notion image
要找数据:【八个扇区为一个页(==一个柱面),一次磁盘IO就是一页 4KB,磁盘读取的最小单位是扇区!
  • 确定柱面号【黄色或者别的部分】
  • 确定盘片号
  • 确定扇区
  • 移动磁头【寻找磁道和盘片/面 需要移动磁头 耗费大量时间】
  • 主轴带动盘面转动
  • 读取和传输数据
预读:把周围的扇区的数据读出来,避免移动磁头,叫做预读!
为什么把页(这里说的也是,MySQL的多个页(一个页16KB,也就是4个柱面))划分到一起,就是为了避免随机IO,能够预读。效率更高
粗略了解MySQL锁粗略了解MySQL查询过程?
Loading...