当前位置 : 主页 > 编程语言 > 其它开发 >

第4章 从一条记录说起—InnoDB记录存储结构

来源:互联网 收集:自由互联 发布时间:2022-06-07
4.1 准备知识 MySQL服务器中负责对表中的数据进行读取和写入工作的部分是存储引擎。而服务器又支持不同类型的存储引擎,比如InnoDB、MyISAM、MEMORY等。 4.2 InnoDB页简介 InnoDB是一个将表中
4.1 准备知识

MySQL服务器中负责对表中的数据进行读取和写入工作的部分是存储引擎。而服务器又支持不同类型的存储引擎,比如InnoDB、MyISAM、MEMORY等。

4.2 InnoDB页简介

InnoDB是一个将表中的数据存储到磁盘上的存储引擎。

真正处理数据的过程发生在内存中,所以需要把磁盘中的数据加载到内存中。

InnoDB采取的方式是,将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位。InnoDB中页的大小一般为16KB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。

4.3 InnoDB行格式
  • 我们平时是以记录为单位向表中插入数据的,记录在磁盘上的存放形式也被称为行格式记录格式
  • InnoDB目前定义了4种不同类型的行格式:COMPACT、REDUNDANT、DYNAMIC、COMPRESSED

指定和修改行格式的语法:

CREATE TABLE 表名(列的信息) ROW_FORMAT=行格式名称;
ALTER TABLE 表名 ROW_FORMAT=行格式名称;
1、COMPACT行格式

一条完整的记录其实可以分为记录的额外信息和记录的真实数据

  • 记录的额外信息

    • 变长字段长度列表

      • 变长字段(比如varchar、varbinary等)占用存储空间分为两部分:真正的数据内容该数据占用的字节数

      • 变长字段长度列表中只存储值为非NULL的列的内容长度,不存储值为NULL的列的内容长度。

      • 并不是所有记录都有这个变长字段长度列表部分,如果表中所有的列都不是变长的数据类型或者所有列的值都是NULL的话,就不需要有变长字段长度列表。

      • 在COMPACT行格式中,所有变长字段的真实数据占用的字节数都存放在记录的开头位置,从而形成一个字段长度列表,各变长字段的真实数据占用的字节数按照列的顺序逆序存放

      • 1、假设某个字符集最多需要M字节来表示一个字符:utf8mb4中W=4,utf8中W=3,bgk中W=2,ASCII中W=1
        2、对于变长类型VARCHAR(M)来说,这种类型表示最多能存储最多M个字符,所以这种类型能表示的字符串最多占用的字节数为M*W
        3、假设该变长字段实际存储的字符串占用的字节数是L
        
        如果变长字段允许存储的最大字节数(M*W)超过255字节,并且真实数据占用的字节数(L)超过127字节,则使用2字节来表示真实数据占用的字节数,否则使用1字节。
        
    • NULL值列表

      • COMPACT行格式把一条记录中值为NULL的列统一管理起来,存储到NULL值列表中。

      • 处理过程:
        1、首先统计表中允许存储NULL的列有哪些
        2、如果表中没有允许存储NULL的列,则NULL值列表也就不存在,否则将每个允许存储NULL的列对应一个二进制位,二进制位按照列的顺序逆序排列。二进制位的值为1,代表该列的值为NULL;二进制位的值为0,代表该列的值不为NULL。
        3、MySQL规定NULL值列表必须用整数个字节的位表示,如果使用的二进制位个数不是整数个字节,则在字节的高位补0。
        
    • 记录头信息

      • 记录头信息由固定的5字节组成,用于描述记录的一些属性
  • 记录的真实数据

    • InnoDB表的主键生成策略:优先使用用户定义的主键作为主键;如果没有定义主键,则选取一个不允许存储NULL值的UNIQUE键作为主键;如果表中连不允许存储NULL值的UNIQUE键都没有定义,则InnoDB会为表默认添加一个名为row_id的隐藏列作为主键
      
    • 除了记录真实数据,MySQL会为每个记录默认地添加一些列(也称为隐藏列),这些隐藏列的值不用我们操心,InnoDB存储引擎会自动帮我们生成

    • 列名 是否必需 占用空间 描述 row_id 否 6字节 行ID,唯一标识一条记录 trx_id 是 6字节 事务ID roll_pointer 是 7字节 回滚指针

CHAR(M)列的存储格式

对于CHAR(M)类型的列来说,当列采用的是定长编码的字符集(例如ASCII)时,该列占用的字节数不会被加到变长字段长度列表;而如果采用变长编码字符集(例如bgk、utf8)时,该列占用的字节数就会被加到变长字段长度列表。
2、REDUNDANT行格式
  • 记录的额外信息

    • 字段长度偏移列表
      • REDUNDANT行格式会把该条记录中所有列(包括隐藏列)的长度信息都按照逆序存储到字段长度偏移列表
      • 采用两个相邻偏移量的差值来计算各个列值的长度
    • 记录头信息
      • REDUNDANT行格式的记录头信息占用6字节,总计48个二进制位
  • 记录的真实数据

    • 直接使用整个记录的真实数据占用的字节长度来决定使用1字节还是2字节存储列对应的偏移量。只要整条记录的真是数据占用的存储空间长度大于127字节,即使某个列的值占用的存储空间不大于127字节,也需要使用2字节来表示该列对应的偏移量


REDUNDANT行格式中NULL值的处理

  • 将列对应的偏移量值的第一个比特位作为是否为NULL的依据,该比特位也可以称之为NULL比特位
  • 如果存储NULL值的字段是定长类型的,比如是CHAR(M)数据类型的,则NULL值也将占用记录的真实数据部分,并把该字段对应的数据使用0x00字节填充。
  • 如果存储NULL值的字段是变长数据类型的,则不在记录的真实数据部分占用任何存储空间

CHAR(M)列的存储格式

REDUNDANT行格式十分干脆,不管该列使用的字符集是啥,只要使用CHAR(M)类型,该列的真实数据占用的存储空间大小就是该字符集表示一个字符最多需要的字节数和M的乘积。

溢出列

如果一条记录的某个列中存储的数据占用的字节数非常多时,该列就可能成为溢出列

3、DYNAMIC行格式和COMPRESSED行格式

这两种行格式类似于COMPACT行格式,只不过在处理溢出列数据时有点儿分歧:它们不会在记录的真实数据处存储列真实数据前768字节,而是把所有的数据都存储到所谓的溢出页中,只在记录的真实数据处存储指向这些溢出页的地址。另外,COMPRESSED行格式会采用压缩算法对页面进行压缩。

上一篇:MySQL安装配置
下一篇:没有了
网友评论