前言
本讲主要探讨的问题是: 数据库表结构底层是怎样的?
索引组织表
按照索引组织的表结构
默认使用主键作为条件, 组织起来的表结构
如果主键不存在怎么办?
看看是否存在唯一索引, 存在拿来当主键
存在多个, 按照顺序找第一个唯一索引
不存在innoDB
引擎自己生成一个主键_rowid
InnoDB
逻辑存储结构
逻辑上, 表空间是所有mysql数据最大的存储容器
表空间还分为段, 区, 页和行(16kb
)
下面的内容看看就行了, 除非面试官真的恶心人, 否则一般不会问
我们只要知道一个页
16kb
, 一个指针在mysql
中是6byte
页是
innoDB
引擎管理的最小单位, 还有数据页内部存储结构章节之后基本没啥是重点
表空间怎么定义的?
表空间是所有mysql数据最大的存储容器
默认情况下, mysql只有一个共享表空间, 用于存储所有数据, 但是你可以配置
如果配置了innodb_file_per_table
配置, 则每张表都产生一个表空间用于存放数据
Q: 那共享表空间就没用了?
A: 不, 单独表只存放: 数据, 索引和插入缓冲bitmap页
其他的数据都存放在共享表空间中, 比如回滚信息, 插入缓冲索引页, 系统事务信息和二次写缓冲等还是存放在共享表空间
段
表空间是由段组成
在上面的那张图中我们发现, 表空间由三个段组成
- 数据段(叶子节点)
- 索引段(非叶子节点)
- 回滚段
区
区由多个页组成, 每个区1mb
大小, 每个数据页16kb
大小
一个区有 64
个页
innodb
为了保证读取的的页数据是完整的, 每次读取都是4~5
区
区的大小通常是不变的, 但是页的大小可以改变
页
页是innoDB
引擎管理的最小单位, 一般是16kb
大小
常见的页有:
- 数据页
- undo 页
- 系统页
- 事务数据页
- 插入缓冲位图页
- 插入缓冲空间列表页
- 未压缩的二进制大对象页
- 压缩的二进制大对象页
行
innoDB
存储引擎是按照行来存储的, 而且每个页对行的行数是有限定的, 最多只能存放 16 kb / 2 - 200 = 7992
行数据
面试题: mysql
的varchar
能存储多少字节?
存放 65532
个字节(latin1
格式)
如果是utf-8
(21845)或者GBK
(32767)则不能存储65532
个字节
这里的定义是针对一张表中所有
varchar
类型的总字节大小不能超过65535
个字节
数据页内部存储结构
infirmum和supermum record
这里两个虚拟记录用于限定数据页的边界使用
这个知识点就跟: 谈谈mysql mvcc和锁 - 掘金 (juejin.cn) 章节的图联系上了
page directory
(页目录)
数据页中的数据是有序的, 比如主键顺序
页目录存放的是页中每个row
的相对位置并且他是稀疏目录, 也就说一个页目录的slot
可能存在多个row
这样可以在数据页中快速定位到row
innoDB
引擎无法找到row
, 只能找到数据页在数据页中查找
row
, 就需要借助page directory
进行查找