前言
本讲主要探讨的问题是: 数据库表结构底层是怎样的?
索引组织表
按照索引组织的表结构
默认使用主键作为条件, 组织起来的表结构
如果主键不存在怎么办?
看看是否存在唯一索引, 存在拿来当主键
存在多个, 按照顺序找第一个唯一索引
不存在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进行查找