《MySQL 技术内幕》表

前言

  • 表就是关于特定实体的数据集合(关系型数据库模型的核心)

索引组织表

  1. InnoDB 存储引擎中的表是根据主键顺序组织存放的,这种存储方式的表称为 索引组织表
  2. InnoDB 存储引擎表中都有一个主键(Primary Key),若未显示定义,则按以下方式选择或创建主键
    • 首先判断表中是否有 非空 唯一索引,如果有,则该列即为主键
      • 若存在多个 非空 唯一索引,将选择建表时第一个定义的非空唯一索引作为主键
      • 根据的是定义 索引 的顺序,而非建表时列的顺序
    • 如果不符合上述条件,InnoDB 自动创建一个 6 字节大小的指针(rowid

InnoDB 逻辑存储结构

  • InnoDB 逻辑存储结构
    image-20190217125716066
  • 所有数据都被逻辑地存放在一个空间中,称为 表空间
  • 表空间 又由 段(segment)、区(extend)、页(page)组成
    • 页在一些文档中也称为 块(block)
  1. 表空间
    • 表空间可以看做是 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 版本中是默认格式
  1. Compact 行记录格式
    • Compact 行记录是在 MySQL 5.0 中引入,设计目标是高效地存储数据
      • 一个页中存放的行数据越多,其性能就越高
    • Compact 行记录的格式
      image-20190217125802897
      • 首部是一个非 NULL 变长字段长度列表,其按照列的顺序逆序放置
      • 第二部分是 NULL 标志位,用于指示了该行数据中是否有 NULL 值
        • 有则用 1 表示
        • 栗子:06 (转换成 二进制 为 00000110 ,则表示 第二列 和 第三列 为 NULL
        • 在 Compact 格式下 NULL 值都不占用任何存储空间
      • 第三部分是 记录头信息,固定占用 5 字节(40位)
        image-20190217125858689
      • 最后的部分就是实际存储每个列的数据( NULL 不占该部分任何空间!
      • 每行数据还有 2 个隐藏列,事务 ID 列(6字节)和 回滚指针列(7字节)
      • 若 InnoDB 表没有定义主键,每行还会增加一个 6 字节的 rowid 列
    • 在 记录头信息中 包含了 下一个记录的偏移量
      • 即在当前位置的基础上加上偏移量 就是 下条记录的起始位置
      • InnoDB 在页内部是通过一种 链表 的数据结构来串连各个行记录
  2. Redundant 行记录格式
    • Redundant 是 MySQL 5.0 版本之前的 InnoDB 的行记录存储方式
      image-20190217125955440
      • 首部是一个字段长度偏移列表,按照列的顺序 逆序 放置
      • Redundant 记录头信息
        image-20190217130014555
  3. 行溢出数据
    • InnoDB 可以将一条记录中的某些数据存储在真正的数据页面之外
      • 通常情况下,InnoDB 的数据都是存放在页类型为 B-tree node 中
      • 当发生行溢出时,数据存放在页类型为 Uncompress BLOB 页中
    • 对应行溢出数据,其存放采用如下方式
      image-20190217130043761
    • 为了保证每个页中至少应该有两条行记录,当 VARCHAR类型的数据的长度超过阈值时,溢出数据
      • 阈值的长度为 8099
    • 大多数情况下 BLOB 的行数据会发生行溢出
      • 实际数据保存在 BLOB 页中
      • 数据页只保存数据的钱 768 字节
  4. Compressed 和 Dynamic 行记录格式
    • InnoDB 1.0.x 版本开始引入新的文件格式:Barracuda
      • Barracuda 文件格式下拥有两种新的行记录格式:Compressed 和 Dynamic
      • Antelope 文件格式下拥有两种行记录格式:Compact 和 Redundant
    • 新的行记录格式对应存放在 BLOB 中的数据采用了 完全 的行溢出方式
      image-20190217130127681
    • Compressed 行记录格式 还支持 存储在其中的行数据以 zlib 的算法进行压缩
  5. CHAR 的行结构存储
    • CHAR 类型被明确视为 变长字符类型(VARCHAR),对应未能占满长度的字符还是填充 0x20
    • CHAR 和 VARCHAR 的实际行存储基本是没有区别的

视图

  • 视图(VIEW)是一个命名的虚表,由一个 SQL 查询来定义,可以当做表使用
    • 与持久表不同的是,视图中的数据没有实际的物理存储
  • 视图的主要用途是被用做一个抽象装置,不需要关系基表的结构,只需要按照视图定义来读取或更新
    • 一定程度上起到一个安全屋的作用
  • 物化视图
    • 物化视图不是基于基表的需表,而是根据基表实际存在的实表
      • 物化视图的数据存储在非易失的存储设备上
    • 主要用于预先计算并保持多表的链接(JOIN)或聚集(GROUP BY)等耗时较多的 SQL 操作结果
      • 好处:对应一些复杂的统计类查询能够直接查出结果
    • MySQL 不支持物化视图,Oracle 、SQL Server 等支持
发布了98 篇原创文章 · 获赞 197 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/YangDongChuan1995/article/details/87567833