Innodb 存储引擎表
索引组织表
Innodb 存储引擎表中,数据都是根据主键顺序存放,这种结构成为索引组织表,所以数据即索引,索引即数据。如果没有显式定义主键,MySQL将按如下方式选举主键:
判断表中是否有唯一非空索引,如果有 以第一个建立索引 的唯一非空索引列为主键,不是表字字段定义顺序。
# 如下的表,c 类最先定义唯一非空主键,所以列c是主键。
create table table_first (
a integer not null,
b char(10) not null,
c integer not null,
UNIQUE KEY(c),
UNIQUE KEY(b),
UNIQUE KEY(a)
);
如果无,Innodb 会自动创建一个6字节大小的主键。
_rowid 与表的主键列值一致,但是它只使用主键是单个列,且它对MySQL自动生成的主键无效。
B+树索引本身并不能找到某一个具体的行记录,而是找到其所在的页并加载到内存中,再根据页中的信息进行查找。
Innodb逻辑存储结构
Innodb 将所有数据都存放到一个逻辑表空间,表空间由:段、区、页组成。

表空间
表空间是Innodb存储引擎逻辑结构的最高层,表的所有数据都存放在表空间中,默认情况下,Innodb有一个默认表空间ibdata1,所有数据都存放在该共享表空间中。可以通过配置项innodb_file_per_table = ON ,所有表会创建一个自己独立的表空间;此时表的数据、索引、和插入缓冲Bitmap页都存放到自己独立的表空间中,除此之外其它数据如:回滚信息、插入缓冲索引页、系统事务信息、二次写缓冲(double write buffer) 等还是存放于共享表空间中。
段
表空间有各个段组成,段分为:数据段、索引段、回滚段等。数据段存放的是聚集索引B+树的叶子节点;索引段存放的是B+树的非叶节点;回滚段存放的是 undo信息。
区
段由区组成,每个区又是由连续的页组成的空间,每个区固定大小为:1M;一般为保证页的连续性,innodb 存储引擎一般每次会连续申请4~5个区;
页
页是innodb磁盘管理的最小单位,每个页默认16K,也就是说默认一个区有64个页;当让 innodb_page_size 配置项可以配置页的大小:4k、8k、16k,设置该大小后不可变,除非重新建表重新导入数据。

常见的页有:
数据页 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
行
Innodb存储引擎是面向列的,也就是数据是按行就行存储的,每个页最多存放:16Kb / 2 - 200 = 7992 行记录。
Innodb 行记录格式
前边提到数据以行的形式存储在页上,那么肯定有一定的格式以便于读取;Innodb内部是通过链表来串接各个行记录的。
由于Innodb 是B+树索引组织的,那么需要保证每个页最少存在两条行记录,否则B+树将分裂成链表,这没有任何意义。如果页不能存下两条记录,那么就会进行溢出以确保页上最少两条记录。
例如某个行记录数据合计9k,那么一个页16K,肯定无法保存两条 9k 的数据的,那么保存时就会进行溢出操作,
Innodb 提供如下的行记录格式:
Compact
它的设计目的是为了高效的存储数据(一个页中存放的行数越多,性能越好)。变长字段的长度不超过2字节,所以MySQL中,varchar最大长度限制为:65535。还有一个需要注意的是,这里的变长字段最大长度,指的是:表中所有变长字段长度的总和,如果按照如下方式定义一个表,就会报错,因为两个边长列的长度合计7W:
create table large_name (
a varchar(40000),
b varchar(30000)
);
Compact 格式下NULL值不占用任何空间。
Compact 行记录格式

Compact 记录头信息

看看字段:next_record 长度 16 位,也就是 2byte, 它表示的是下一个字段的位置,所以说长度总和不能超过 65536.
如下表,字段b的起始位置大概就是:65534
create table large_name (
a varchar(65533),
b varchar(2)
);
Redundant
它是MySQL5.0版本之前的行记录存储方式,支持该格式只是问了兼容旧版本行格式。
行溢出数据
Innodb 存储引擎可以将行记录的某些数据存储在该行记录所在的页之外,一般会把 BLOB、LOB 等这类大对象列类型的数据存放到页面之外。实际上,由于页的大小为:16K,那么是否溢出完全由数据的大小来决定,当内容足够少,blob 页可能不回溢出当前页,varchar类型当足够大的时候也可能发生溢出。
varchar(30000) 值的是3W个字节,而页大小为:16K 也就是 16384 字节,所以完全可能溢出。
对行溢出数据,页中行记录会保留其前768个字节的数据。

Compressed 和 Dynamic 行记录格式
这是Innodb 中较新的行记录格式,他们对BLOB 数据的存储采用了完全的行溢出方式,数据页中只存放20字节的 指针,实际数据都存放于Off Page 中。

char 的行结构存储
- varchar 指变长字符类型
- char指定长字符类型,计算实际不足,也会分配相应长度的空间
从 MySQL4.1 开始,char(N) 表示N个字符,而不是N个字节的字符,
但是在多字节字符集情况下,char 和 varchar保存方式一致,例如:char (10) 可以存放 10个英文字符,也可以存放 10 个汉字;此时,他们的长度就不一致了,前者共占用10字节,而保存10个汉字则需要20 字节。
当然,不论存放汉字或者英文字符,只要不足定义的10个字符,还是会进行填充。
Innodb 数据页结构

File Header 文件头,占用38字节,记录页的一些头信息。
Page Header 页头,由14个部分组成,占用56字节,记录数据页的状态信息
Infimum和Supremum Record 虚拟的行记录,用来限定记录的边界
Infimum 记录比页中任何主键值都要小的值,Supremum 记录页中比任何主键都要大的值;它们在页串创建时被创建,任何情况下都不会被删除。

User Record 用户记录,即行记录,它指实际存储的行记录内容
Free Space 页的空闲空间,当一条记录被删除后,该空间会被加入到空闲列表中,它是链表组织结构的
Page Directory 页目录,存放记录的相对地址(不是偏移量)
这些记录指针称为:Slots(槽)或者 Directory Slots (目录槽),需要注意的是,Innodb中它是一个稀目录,并不是每个行记录都拥有一个槽,也就是说可能一个槽中包含多个记录;由于它是一个稀目录,二叉查找的结果也只是一个粗略的结果。
B+树索引本身并不能找到某一个具体的行记录,而是找到其所在的页,然后将其加载到内存中,再通过Page Directory进行二叉查找,最后再结合 【行记录头】中的【next record】精确定位到实际的行记录。
行记录头参考上述对Compact 格式行记录的描述。
- File Trailer 文件结尾信息,检测页是否已经完整地写入磁盘,可以理解成它是用来支持做页的校验和的。
视图 View
MySQL中,视图是一个命名的虚表,他由一个SQL查询来定义,可以当作表使用。
分区表
当数据量较大是可以进行分表操作
- 水平拆分,将同一个表中不同行的记录进行拆分,即按行拆分。
- 垂直拆分,将同一个表中不同列的记录进行拆分,即对表按列进行拆分。
看完书,其实MySQL自身支持的分区表功能并不够强大,当数据量膨胀时,可以考虑 当当 共享给apache 的开源项目 shardingspwhere ,目前它已经时apache 的顶级开源项目之一。
本文来自我对 《MySQL技术内幕:InnoDB存储引擎》一书阅读过后的二次创作,文件颇多截图引用书中插图,此外本文主要用作个人学习后的思考感悟的记录,肯定不如原书讲得深入且全面,强烈建议购买原书深入了解更多的细节。
Innodb 存储引擎表的更多相关文章
- InnoDB存储引擎表的主键
在InnoDB存储引擎中,表是按照主键顺序组织存放的.在InnoDB存储引擎表中,每张表都有主键(primary key),如果在创建表时没有显式地定义主键,则InnoDB存储引擎会按如下方式选择或创 ...
- InnoDB存储引擎表的逻辑存储结构
1.索引组织表: 在InnoDB存储引擎中,表都是依照主键顺序组织存放的.这样的存储方式的表称为索引组织表,在innodb存储引擎表中,每张表都有主键.假设创建的时候没有显式定义主键,则Inn ...
- INNODB存储引擎表空间
这片文章主要是对innodb表空间的一些说明: innodb中表空间可以分为以下几种: 系统表空间 独立表空间 undo表空间 临时表空间(temporary tablespace) 通用表空间(ge ...
- (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁
表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...
- MySQL技术内幕InnoDB存储引擎(表&索引算法和锁)
表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示 ...
- MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析
文/何登成 导读: 来自网易研究院的MySQL内核技术研究人何登成,把MySQL数据库InnoDB存储引擎的多版本控制(简称:MVCC)实现原理,做了深入的研究与详细的文字图表分析,方便大家理解I ...
- MySQL InnoDB存储引擎中的锁机制
1.隔离级别 Read Uncommited(RU):这种隔离级别下,事务间完全不隔离,会产生脏读,可以读取未提交的记录,实际情况下不会使用. Read Committed (RC):仅能读取到已提交 ...
- InnoDB存储引擎介绍-(5) Innodb逻辑存储结构
如果创建表时没有显示的定义主键,mysql会按如下方式创建主键: 首先判断表中是否有非空的唯一索引,如果有,则该列为主键. 如果不符合上述条件,存储引擎会自动创建一个6字节大小的指针. 当表中有多个非 ...
- 参数innodb_force_recovery影响了整个InnoDB存储引擎的恢复状况
参数innodb_force_recovery影响了整个InnoDB存储引擎的恢复状况.该值默认为0,表示当需要恢复时执行所有的恢复操作.当不能进行有效恢复时,如数据页发生了corruption,My ...
- 《MySQL技术内幕:InnoDB存储引擎(第2版)》书摘
MySQL技术内幕:InnoDB存储引擎(第2版) 姜承尧 第1章 MySQL体系结构和存储引擎 >> 在上述例子中使用了mysqld_safe命令来启动数据库,当然启动MySQL实例的方 ...
随机推荐
- [转帖]阿里云Redis开发规范(供大家参考)
一.键值设计 1. key名设计 (1)[建议]: 可读性和可管理性 以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id ugc:video:1 (2)[建议]:简洁性 ...
- [转帖]Linux下AWK、SED、GREP、FIND命令详解
https://www.jianshu.com/p/d54e0359db01 AWK AWK是一个优良的文本处理工具,Linux和Unix环境中现有的功能最强大的数据处理引擎之一. 语法 awk [选 ...
- [转帖]配置logback上报日志到Skywalking
https://zhuanlan.zhihu.com/p/506119895 配置logback上报日志到Skywalking 配置logback上报日志到skywalking需要引入toolkit依 ...
- [转帖]@nginx多server及使用优化(php)
文章目录 一.nginx多server优先级 二.禁止IP访问页面 三.nginx的包含include 四.nginx 路径的alias和root 1.配 ...
- systemctl 关闭图形界面的办法
开机以命令模式启动,执行: systemctl set-default multi-user.target 开机以图形界面启动,执行: systemctl set-default graphica ...
- awk的简要使用
原文地址:https://www.lujun9972.win/blog/2020/08/23/在命令行进行简单的统计分析/index.html 目录 使用awk获取最小值.最大值.中位数和平均值 使用 ...
- 【NSSCTF-Round#16】 Web和Crypto详细完整WP
每天都要加油哦! ------2024-01-18 11:16:55 [NSSRound#16 Basic]RCE但是没有完全RCE <?php error_reporting(0); ...
- RabbitMQ集成系统文章02---webForm发布 ABP VNext订阅
一.webForm项目中发布 1.引用RabbitMQ.Client 2.在你想要发布的地方调用如下的方法 public void PublishRabbitMQ() { var data = new ...
- Go实现网络代理
使用 Go 语言开发网络代理服务可以通过以下步骤完成.这里,我们将使用 golang.org/x/net/proxy 包来创建一个简单的 SOCKS5 代理服务作为示例. 步骤 1. 安装 golan ...
- Fabric网络升级(总)
原文地址在这里. 在fabric网络中,升级nodes和通道至最新版本需要四步: 备份账本和MSPs. 以滚动的方式将orderer升级到最新版. 以滚动的方式将peers升级到最新版. 将order ...