这一节本来计划开始索引的学习,但是在InnoDB存储引擎的索引里,存在一些数据存储结构的概念,这一节先了解一下InnodDB的逻辑存储结构,为索引的学习打好基础。

从InnoDB存储引擎的存储结构看,所有数据都被逻辑地放在一个空间中,称之为表空间(tablespace)、区(extent)、页(page)组成,页在一些文档中也被称之为块(block)。

1、InnoDB逻辑存储结构

InnoDB存储引擎的逻辑存储结构大致如图:

这张图更清晰地展示了这些空间的包含关系:

1.1、表空间(Tablespace)

表空间可以看做InnoDB逻辑结构的最高层,所有的数据都放在表空间中。

在默认情况下,InnoDB存储引擎都有一个共享表空间ibdata1,即所有数据都存放在这个表空间内。如果用户启用了参数innodb_file_per_table,则每张表内的数据可以单独放到一个表空间内。

如果启用了innodb_file_per_table参数,也需要注意,每张表的表空间存放的只是数据、索引和插入缓冲Bitmap页,其它类的数据,如回滚(undo)信息,插入缓冲索引页、系统事务信息,二次写缓冲等还是存放在原来的共享表空间内。

1.2、段(Segment)

表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等。

InnoDB存储引擎表是索引组织(index organized)的,因此数据即索引,索引即数据。那么数据段即为B+树的叶子节点(Leaf node segment),索引段即为B+树的非索引节点(Non-leaf node segment),这些内容在后面的索引学习里会详细介绍。

1.3、区(extend)

区是由连续页组成的空间,在任何情况下每个区的大小都为1MB。为了保证区中页的连续性,InonoDB存储引擎一次从磁盘申请4-5个区。在默认情况下,InnoDB存储引擎的页的大小为16KB,即一个区中应有64个连续的页。

InnoDB1.0.x版本开始引入压缩页,每个页的大小可以通过参数KEY_BLOCK_SIZE设置为2K、4K、8K,因此每个区对应的页尾512、256、128.

InnoDB1.2.x版本新增了参数innodb_page_size,通过该参数可以将默认页的大小设置为4K、8K,但是页中的数据不是压缩的。

但是有时候为了节约磁盘容量的开销,创建表默认大小是96KB,区中是64个连续的页。(对于一些小表)

1.4、页(page)

页是InnoDB存储引擎磁盘管理的最小单位,每个页默认16KB;InnoDB存储引擎从1.2.x版本开始,可以通过参数innodb_page_size将页的大小设置为4K、8K、16K。

若设置完成,则所有表中页的大小都为innodb_page_size,不可以再次对其进行修改,除非通过mysqldump导入和导出操作来产生新的库。

innoDB存储引擎中,常见的页类型有:

数据页(B-tree Node)

undo页(undo Log Page)

系统页 (System Page)

事务数据页 (Transaction System Page)

插入缓冲位图页(Insert Buffer Bitmap)

插入缓冲空闲列表页(Insert Buffer Free List)

未压缩的二进制大对象页(Uncompressed BLOB Page)

压缩的二进制大对象页 (compressed BLOB Page)

1.5、行(row)

InnoDB存储引擎是面向行的(row-oriented),也就是说数据是按行进行存放的,每个页存放的行记录也是有硬性定义的,最多允许存放16KB/2-200,即7992行记录。

2、InnoDB 行记录格式

InnoDB 存储引擎和大多数数据库一样(如 OracleMicrosoft SQL Server 数据库),记录是以行的形式存储的。这意味着页中保存着表中一行行的数据。在 InnoDB 1.0x 版本之前,InnoDB 存储引擎提供了 CompactRedundant 两种格式来存放行记录数据,这也是目前使用最多的一种格式。

2.1、Compact 行记录格式

Compact 行记录是在 MySQL 5.0 中引人的,其设计目标是髙效地存储数据。简单来说,一个页中存放的行数据越多,其性能就越髙。

下图显示了 Compact 行记录的存储方式:

Compact 行记录格式的首部是一个非 NULL 变长字段长度列表,并且其是按照列的顺序逆序放置的,其长度为:

  • 若列的长度小于 255 字节,用 1 字节表示;

  • 若大于 255 个字节,用2 字节表示。

变长字段的长度最大不可以超过 2 字节,这是因在 MySQL 数据库中 VARCHAR 类型的最大长度限制为 65535。变长字段之后的第二个部分是 NULL 标志位,该位指示了该行数据中是否有 NULL 值,有则用 1 表示。

接下来的部分是记录头信息(record header),固定占用5 字节(40 位)。每位含义见表:

名称 大小(bit) 描述
() 1 未知
() 1 未知
deleted_flag 1 该行是否已被删除
min_rec_flag 1 如果该行记录是预定义为最小的记录,为1
n_owned 4 该记录拥有的记录数,用于Slot
heap_no 13 索引堆中该条记录的索引号
record_type 3 记录类型,000(普通),001(B+Tree节点指针),010(Infimum),011(Supremum)
next_record 16 页中下一条记录的相对位置
Total 40(5Byte) nothing

最后的部分就是实际存储每个列的数据。

需要特别注意的是,NULL 不占该部分任何空间,即 NULL 除了占有 NULL 标志位,实际存储不占有任何空间。另外有一点需要注意的是,每行数据除了用户定义的列外,还有两个隐藏列,事务 1D 列和回滚指针列,分别为 6 字节和 7 字节的大小。若 InnoDB 表没有定义主键,每行还会增加一个 6 字节的 rowid 列。

RedundantMySQL 5 . 0 版本之前 InnoDB 的 行 记 录 存 储 方 式,这里就不展开。

2.2、行溢出数据

InnoDB 存储引擎可以将一条记录中的某些数据存储在真正的数据页之外。因为一般数据页默认大小为16KB,假如一个数据页存储不了插入的数据,这时肯定就会发生行溢出。

一般认为 BLOBLOB 这类的大对象列类型的存储会把数据存放在数据页之外。但是,BLOB 也可以不将数据放在溢出页面,而且即便是 VARCHAR 列数据类型,依然有可能被存放为行溢出数据。

3、InnoDB 数据页结构

页是 InnoDB 存储引擎管理数据库最小磁盘单位。页类型为 B-tree Node 的页存放的即是表中行的实际数据了。

InnoDB 数据页由以下 7 个部分组成:

  • File Header (文件头)

  • Page Header (页头)

  • InfimunSupremum Records

  • User Records (用户记录,即行记录)

  • Free Space (空闲空间)

  • Page Directory (页目录)

  • File Trailer (文件结尾信息)

其中 File HeaderPage HeaderFile Trailer的大小是固定的, 分别为 38、56、8 字节,这些空间用来标记该页的一些信息,如 Checksum, 数据页所在 B+ 树索引的层数等。User RecordsFree SpacePage Directory 这些部分为实际的行记录存储空间,因此大小是动态的。


参考:

【1】:《MySQL技术内幕 InnoDB存储引擎》

【2】:MySQL Architecture and Components

【3】:了解 MySQL的数据行、行溢出机制吗?

【4】:InnoDB数据页结构分析

【5】:InnoDB数据页结构

【6】:InnoDB -- 行记录格式

MySQL提升笔记(4)InnoDB存储结构的更多相关文章

  1. 《MySQL技术内幕:InnoDB存储引擎(第2版)》书摘

    MySQL技术内幕:InnoDB存储引擎(第2版) 姜承尧 第1章 MySQL体系结构和存储引擎 >> 在上述例子中使用了mysqld_safe命令来启动数据库,当然启动MySQL实例的方 ...

  2. 《MySQL技术内幕:InnoDB存储引擎》读书笔记

    一.Mysql体系结构和存储引擎 1. 概念:              数据库:物理操作系统文件或其他形式文件类型的集合.(是文件的集合,是依照某种数据模型组织起来并存放于二级存储器中的数据集合.) ...

  3. MySQL笔记(2)---InnoDB存储引擎

    1.前言 本节记录InnoDB的相关知识点. 2.InnoDB存储引擎简介 2.1版本 MySQL5.1开始,允许用动态方式加载引擎,这样存储引擎的更新可以不受MySQL数据库版本的限制.下面是各个I ...

  4. MySQL提升笔记(2):存储引擎盘点

    在前面我们了解了server层调用存储引擎层接口来完成sql的执行,使用存储引擎的好处是:每个存储引擎都有各自的特点,能够根据具体的应用建立不同存储引擎表. 需要注意的是,存储引擎是基于表的,而不是数 ...

  5. [MySQL Reference Manual]14 InnoDB存储引擎

    14 InnoDB存储引擎 14 InnoDB存储引擎 14.1 InnoDB说明 14.1.1 InnoDB作为默认存储引擎 14.1.1.1 存储引擎的趋势 14.1.1.2 InnoDB变成默认 ...

  6. MySQL提升笔记(3)日志文件详解

    在MySQL数据库和InnoDB存储引擎中,有很多种文件,如:参数文件.日志文件.socket文件.pid文件.MySQL表结构文件.存储引擎文件. 本节重点关注日志文件,MySQL的复制.事务等重要 ...

  7. MySQL学习笔记七:存储引擎

    1.MySQL存储引擎的设计采用“插件式”方案,用户可以很方便地选择使用哪种存储引擎,想使用mysql没有提供的引擎时,可以自己安装进去. 查看支持的存储引擎 mysql> show engin ...

  8. MySQL数据库MyISAM和InnoDB存储引擎的比较

    MySQL有多种存储引擎,MyISAM和InnoDB是其中常用的两种.这里介绍关于这两种引擎的一些基本概念(非深入介绍). MyISAM是MySQL的默认存储引擎,基于传统的ISAM类型,支持全文搜索 ...

  9. 《Mysql技术内幕,Innodb存储引擎》——文件、表

    文件 日志 错误日志 对Mysql启动.运行和关闭过程进行记录,通过SHOW VARIABLES LIKE 'log_error'查看日志文件位置. 慢查询日志 Mysql启动时设置一个阈值,运行时间 ...

随机推荐

  1. Oracle数据库配置监听程序

    最近在学习Oracle数据库,从安装到配置监听程序基本靠百度... 不得不说百度真的很nice!!! 下面是我的Oracle服务端(PL/SQL Developer)出现的监听程序的问题及我解决的方法 ...

  2. 第七届蓝桥杯JavaB组——第6题方格填数

    解决方案:利用全排列和递归 使用Java中的集合API:HashMap ArrayList package com.lzp.lanqiaoseven.p6; import java.util.*; / ...

  3. 图像分割 | Context Prior CPNet | CVPR2020

    文章转自微信公众号:「机器学习炼丹术」 文章作者:炼丹兄(已授权) 作者联系方式:cyx645016617 论文名称:"Context Prior for Scene Segmentatio ...

  4. 读懂一个中型的Django项目

    转自https://www.cnblogs.com/huangfuyuan/p/Django.html [前言]中型的项目是比较多的APP,肯会涉及多数据表的操作.如果有人带那就最好了,自己要先了解基 ...

  5. VMware 安装 CentOS7 后的简单配置

    1.连网 如果能连网,跳过此步 试着ping一下百度 ping baidu.com 动态分配 IP sudo vim /etc/sysconfig/network-scripts/ifcfg-ens3 ...

  6. 如何使用 Github Actions 自动抓取每日必应壁纸?

    如何白嫖 Github 服务器自动抓取必应搜索的每日壁纸呢? 如果你访问过必应搜索网站,那么你一定会被搜索页面的壁纸吸引,必应搜索的壁纸每日不同,自动更换,十分精美.这篇文章会介绍如何一步步分析出必应 ...

  7. HDR(高动态范围)

    一: 简介 一般来说,当存储在帧缓冲(Framebuffer)中时,亮度和颜色的值是默认被限制在0.0到1.0之间的. 但是如果我们遇上了一个特定的区域,其中有多个亮光源使这些数值总和超过了1.0,又 ...

  8. 解决:layUI数据表格+简单查询

    解决:layUI数据表格+简单查询 最近在用layui写项目,在做到用户查询时,发现在layui框架里只有数据表格,不能增加查询.于是自己摸索了一下,写个笔记记录一下. 我想要的效果: 1.定义查询栏 ...

  9. Vue入门干货,以及遇到的坑

    一.安装环境及Vue脚手架搭建 参考文档:https://www.jianshu.com/p/1626b8643676 二.开发文档 官方文档:https://cn.vuejs.org/v2/guid ...

  10. 基于dlib+django+python 实现web端人脸打卡

    face_recognition 基于python+django+dlib实现的人脸打卡系统 开始之前 windows用户需要安装 VS2017 其他VS版本也行 linux用户需要安装c++编译器( ...