《MySQL 技术内幕》表
文章目录
前言
- 表就是关于特定实体的数据集合(关系型数据库模型的核心)
索引组织表
- InnoDB 存储引擎中的表是根据主键顺序组织存放的,这种存储方式的表称为 索引组织表
- InnoDB 存储引擎表中都有一个主键(Primary Key),若未显示定义,则按以下方式选择或创建主键
-
首先判断表中是否有 非空 唯一索引,如果有,则该列即为主键
- 若存在多个 非空 唯一索引,将选择建表时第一个定义的非空唯一索引作为主键
- 根据的是定义 索引 的顺序,而非建表时列的顺序
- 如果不符合上述条件,InnoDB 自动创建一个 6 字节大小的指针(rowid
-
首先判断表中是否有 非空 唯一索引,如果有,则该列即为主键
InnoDB 逻辑存储结构
- InnoDB 逻辑存储结构
- 所有数据都被逻辑地存放在一个空间中,称为 表空间
- 表空间 又由 段(segment)、区(extend)、页(page)组成
- 页在一些文档中也称为 块(block)
- 表空间
- 表空间可以看做是 InnoDB 逻辑结构的最高层,所有的数据都存放在表空间中
- 默认情况下,所有数据都存放在 共享表空间 ibdata1 中
- 若启用
innodb_file_per_table
则允许每张表内的数据可以单独放到一个表空间- 但每张表空间只存放 数据、索引和插入缓冲 Bitmap 页
- 其他类的数据(如回滚信息、插入缓冲索引页、系统事务信息、二次写缓冲等)还是存放在原共享表空间内
- 及时启用了
innodb_file_per_table
后,共享表空间还是会不断地增加其大小
- 若启用
- InnoDB 存储引擎不会在执行 rollback 时去收缩这个表空间,只将其标记为可用,供下次undo使用
- 段
- 表空间由各个段组成,常见的段有数据段、索引段、回滚段等
- 数据段: B+ 树的叶子节点
- 索引段: B+ 树的非叶子节点
- InnoDB 存储引擎中,对段的管理都是由存储引擎自身所完成,无法对其进行控制
- 表空间由各个段组成,常见的段有数据段、索引段、回滚段等
- 区
- 区是由连续页组成的空间,在任何情况下每个区的大小都为 1MB
- 为了保证区中页的连续性,InnoDB 存储引擎一次从磁盘申请 4 - 5 个区
- 默认情况下,InnoDB 存储引擎页的大小为 16KB,即一个区中一共有 64 个连续的页
- 每个段开始时,先用32个大小的 碎片页来存放数据,使用完后才是 64 个连续页的申请
- 目的:对于一些小表,开始时申请较少的空间,节省磁盘容量的开销
- 页
- 页是 InnoDB 磁盘管理的最小单位
- 默认每个页的大小为 16KB
- 参数
innodb_page_size
配置默认页的大小
- 参数
- 常见的页类型
- 数据页(B-tree Node
- undo 页(undo Log Page
- 系统页(System Page
- 事务数据页(Transaction system Page
- 插入缓冲位图页
- 未压缩的二进制大对象页
- 压缩的二进制大对象页
- 行
- InnoDB 存储引擎是面向列的(row-orientd),也就说数据时按行进行存放
- 每个页存放的行记录有硬性定义,最多允许存放 16KB / 2-200 行记录,即7992行记录
InnoDB 行记录格式
- InnoDB 存储引擎中,记录是以行的形式存储的,页中保存着表中一行还的数据
- 在 InnoDB 1.0x 版本之前,提供了 Compact 和 Redundant 两种格式存放行记录数据
- Redundant 格式是为了兼容之前版本而保留的
- Compact 格式在 MySQL 5.1 版本中是默认格式
- Compact 行记录格式
- Compact 行记录是在 MySQL 5.0 中引入,设计目标是高效地存储数据
- 一个页中存放的行数据越多,其性能就越高
- Compact 行记录的格式
- 首部是一个非 NULL 变长字段长度列表,其按照列的顺序逆序放置
- 第二部分是 NULL 标志位,用于指示了该行数据中是否有 NULL 值
- 有则用 1 表示
- 栗子:06 (转换成 二进制 为 00000110 ,则表示 第二列 和 第三列 为 NULL
- 在 Compact 格式下 NULL 值都不占用任何存储空间
- 第三部分是 记录头信息,固定占用 5 字节(40位)
- 最后的部分就是实际存储每个列的数据( NULL 不占该部分任何空间!
- 每行数据还有 2 个隐藏列,事务 ID 列(6字节)和 回滚指针列(7字节)
- 若 InnoDB 表没有定义主键,每行还会增加一个 6 字节的 rowid 列
- 在 记录头信息中 包含了 下一个记录的偏移量
- 即在当前位置的基础上加上偏移量 就是 下条记录的起始位置
- InnoDB 在页内部是通过一种 链表 的数据结构来串连各个行记录
- Compact 行记录是在 MySQL 5.0 中引入,设计目标是高效地存储数据
- Redundant 行记录格式
- Redundant 是 MySQL 5.0 版本之前的 InnoDB 的行记录存储方式
- 首部是一个字段长度偏移列表,按照列的顺序 逆序 放置
- Redundant 记录头信息
- Redundant 是 MySQL 5.0 版本之前的 InnoDB 的行记录存储方式
- 行溢出数据
- InnoDB 可以将一条记录中的某些数据存储在真正的数据页面之外
- 通常情况下,InnoDB 的数据都是存放在页类型为 B-tree node 中
- 当发生行溢出时,数据存放在页类型为 Uncompress BLOB 页中
- 对应行溢出数据,其存放采用如下方式
- 为了保证每个页中至少应该有两条行记录,当 VARCHAR类型的数据的长度超过阈值时,溢出数据
- 阈值的长度为 8099
- 大多数情况下 BLOB 的行数据会发生行溢出
- 实际数据保存在 BLOB 页中
- 数据页只保存数据的钱 768 字节
- InnoDB 可以将一条记录中的某些数据存储在真正的数据页面之外
- Compressed 和 Dynamic 行记录格式
- InnoDB 1.0.x 版本开始引入新的文件格式:Barracuda
- Barracuda 文件格式下拥有两种新的行记录格式:Compressed 和 Dynamic
- Antelope 文件格式下拥有两种行记录格式:Compact 和 Redundant
- 新的行记录格式对应存放在 BLOB 中的数据采用了 完全 的行溢出方式
- Compressed 行记录格式 还支持 存储在其中的行数据以 zlib 的算法进行压缩
- InnoDB 1.0.x 版本开始引入新的文件格式:Barracuda
- CHAR 的行结构存储
- CHAR 类型被明确视为 变长字符类型(VARCHAR),对应未能占满长度的字符还是填充 0x20
- CHAR 和 VARCHAR 的实际行存储基本是没有区别的
视图
- 视图(VIEW)是一个命名的虚表,由一个 SQL 查询来定义,可以当做表使用
- 与持久表不同的是,视图中的数据没有实际的物理存储
- 视图的主要用途是被用做一个抽象装置,不需要关系基表的结构,只需要按照视图定义来读取或更新
- 一定程度上起到一个安全屋的作用
- 物化视图
- 物化视图不是基于基表的需表,而是根据基表实际存在的实表
- 物化视图的数据存储在非易失的存储设备上
- 主要用于预先计算并保持多表的链接(JOIN)或聚集(GROUP BY)等耗时较多的 SQL 操作结果
- 好处:对应一些复杂的统计类查询能够直接查出结果
- MySQL 不支持物化视图,Oracle 、SQL Server 等支持
- 物化视图不是基于基表的需表,而是根据基表实际存在的实表