MySQL InnoDB 行记录格式(ROW_FORMAT)
MySQL InnoDB 行记录格式(ROW_FORMAT)
一、行记录格式的分类和介绍
在早期的InnoDB版本中,由于文件格式只有一种,因此不需要为此文件格式命名。随着InnoDB引擎的发展,开发出了不兼容早期版本的新文件格式,用于支持新的功能。为了在升级和降级情况下帮助管理系统的兼容性,以及运行不同的MySQL版本,InnoDB开始使用命名的文件格式。
1. Antelope: 先前未命名的,原始的InnoDB文件格式。它支持两种行格式:COMPACT 和 REDUNDANT。MySQL5.6的默认文件格式。可以与早期的版本保持最大的兼容性。不支持 Barracuda 文件格式。
2. Barracuda: 新的文件格式。它支持InnoDB的所有行格式,包括新的行格式:COMPRESSED 和 DYNAMIC。与这两个新的行格式相关的功能包括:InnoDB表的压缩,长列数据的页外存储和索引建前缀最大长度为3072字节。
在 msyql 5.7.9 及以后版本,默认行格式由innodb_default_row_format
变量决定,它的默认值是DYNAMIC
,也可以在 create table 的时候指定ROW_FORMAT=DYNAMIC
。用户可以通过命令 SHOW TABLE STATUS LIKE'table_name'
来查看当前表使用的行格式,其中 row_format 列表示当前所使用的行记录结构类型。
PS:如果要修改现有表的行模式为compressed
或dynamic
,必须先将文件格式设置成Barracuda:set global innodb_file_format=Barracuda;
,再用ALTER TABLE tablename ROW_FORMAT=COMPRESSED;
去修改才能生效。
mysql> show variables like "innodb_file_format";
+--------------------+-----------+
| Variable_name | Value |
+--------------------+-----------+
| innodb_file_format | Barracuda |
+--------------------+-----------+
1 row in set (0.00 sec)
mysql> show table status like "test%"\G
*************************** 1. row ***************************
Name: test
Engine: MyISAM
Version: 10
Row_format: Dynamic
Rows: 4
Avg_row_length: 20
Data_length: 80
Max_data_length: 281474976710655
Index_length: 1024
Data_free: 0
Auto_increment: NULL
Create_time: 2018-08-07 13:07:59
Update_time: 2018-08-07 13:08:01
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options: row_format=DYNAMIC
Comment:
二、InnoDB行存储
InnoDB表的数据存储在页(page)中,每个页可以存放多条记录。这些页以树形结构组织,这颗树称为B树索引。表中数据和辅助索引都是使用B树结构。维护表中所有数据的这颗B树索引称为聚簇索引,通过主键来组织的。聚簇索引的叶子节点包含行中所有字段的值,辅助索引的叶子节点包含索引列和主键列。
变长字段是个例外,例如对于BLOB和VARCHAR类型的列,当页不能完全容纳此列的数据时,会将此列的数据存放在称为溢出页(overflow page)的单独磁盘页上,称这些列为页外列(off-page column)。这些列的值存储在以单链表形式存在的溢出页列表中,每个列都有自己溢出页列表。某些情况下,为了避免浪费存储空间和消除读取分隔页,列的所有或前缀数据会存储在B+树索引中。
三、Compact 和 Redundant
(一)Compact
Compact行记录是在MySQL5.0中引入的,为了高效的存储数据,简单的说,就是为了让一个页(Page)存放的行数据越多,这样性能就越高。行记录格式如下:
1. 变长字段长度列表:变长字段长度最大不超过2字节(MySQL数据库varcahr类型的最大长度限制为65535)
2. NULL标识位:该位指示了该行数据中是否有NULL值,有则用1。
3. 记录头信息:固定占用5字节(40位)
4. 列N数据:实际存储每列的数据,NULL不占该部分任何空间,即NULL占有NULL标志位,实际存储不占任何空间。
PS:每一行数据除了用户定义的例外,还有两个隐藏列,事物ID列和回滚指针列,分别位6字节和7字节的大小,若InnoDB表没有定义主键,每行还未增加一个6字节的rowid列。
(二)Redundant
MySQL5.0之前的行记录格式:
1. 字段偏移列表:同样是按照列的顺序逆序放置的,若列的长度小于255字节,用1字节表示,若大于255字节,用2字节表示。
2. 记录头信息:占用6字节(48位)
(三)行溢出数据
1. 当行记录的长度
没有超过行记录最大长度
时,所有数据
都会存储在当前页。
2. 当行记录的长度
超过行记录最大长度
时,变长列(variable-length column
)会选择外部溢出页(overflow page
,一般是Uncompressed BLOB Page
)进行存储。
Compact
+ Redundant
:保留前768Byte
在当前页(B+Tree叶子节点
),其余数据存放在溢出页
。768Byte
后面跟着20Byte
的数据,用来存储指向溢出页的指针。
(四)概述
对于 Compact 和 Redundant 行格式,InnoDB将变长字段(VARCHAR, VARBINARY, BLOB 和 TEXT)的前786字节存储在B+树节点中,其余的数据存放在溢出页(off-page),如下图:
上面所讲的讲的blob或变长大字段类型包括blob,text,varchar,其中varchar列值长度大于某数N时也会存溢出页,在latin1字符集下N值可以这样计算:innodb的块大小默认为16kb,由于innodb存储引擎表为索引组织表,树底层的叶子节点为一双向链表,因此每个页中至少应该有两行记录,这就决定了innodb在存储一行数据的时候不能够超过8k,减去其它列值所占字节数,约等于N。
使用Antelope文件格式,若字段的值小于等于786字节,不需要溢出页,因为字段的值都在B+树节点中,所以会降低I/O操作。这对于相对较短的BLOB字段有效,但可能由于B+树节点存储过多的数据而导致效率低下。
四、Compressed 和 Dynamic
InnoDB1.0x开始引入心的文件格式(file format,用户可以理解位新的页格式)——Barracuda(图1),这个新的格式拥有两种新的行记录格式:Compressed和Dynamic。
新的两种记录格式对于存放BLOB中的数据采用了完全的行溢出的方式。如图:
Dynamic行格式,列存储是否放到off-page页,主要取决于行大小,他会把行中最长的一列放到off-page,直到数据页能存放下两行。TEXT或BLOB列<=40bytes时总是存在于数据页。这种方式可以避免compact那样把太多的大列值放到B-tree Node(数据页中只存放20个字节的指针,实际的数据存放在Off Page中,之前的Compact 和 Redundant 两种格式会存放768个字前缀字节)。
Compressed物理结构上与Dynamic类似,Compressed行记录格式的另一个功能就是存储在其中的行数据会以zlib的算法进行压缩,因此对于BLOB、TEXT、VARCHAR这类大长度数据能够进行有效的存储(减少40%,但对CPU要求更高)。
若有不恰当之处,还望指教,谢谢!
参考
1. 《MySQL技术内幕·InnoDB存储引擎》
3. 《MySQL 大字段溢出导致数据回写失败》
MySQL InnoDB 行记录格式(ROW_FORMAT)的更多相关文章
- InnoDB -- 行记录格式
本文转载自InnoDB -- 行记录格式 分类 Named File Format InnoDB早期的文件格式(页格式)为Antelope,可以定义两种行记录格式,分别是Compact和Redunda ...
- Mysql InnoDB行锁实现方式(转)
Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...
- Mysql InnoDB行锁实现方式
Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...
- InnoDB行记录格式(compact)、InnoDB数据页结构
1. compact 行记录格式: 变长字段长度列表,null标志位,记录头信息,列1数据,列2数据 …… 记录头信息中包含许多信息,只列举一部分: 名称 大小 描述 deleted_flag 1bi ...
- mysql innodb 行级锁升级
创建数据表test,表定义如下所示: CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NO ...
- Mysql InnoDB行锁不使用索引锁表的时候会锁整张表
原文:http://www.thinkphp.cn/topic/41577.html 如果使用针对InnoDB的表使用行锁,被锁定字段不是主键,也没有针对它建立索引的话.行锁锁定的也是整张表.锁整张表 ...
- MySQL InnoDB 索引原理
本文由 网易云发布. 作者:范鹏程,网易考拉海购 InnoDB是 MySQL最常用的存储引擎,了解InnoDB存储引擎的索引对于日常工作有很大的益处,索引的存在便是为了加速数据库行记录的检索.以下是 ...
- Innodb物理存储结构系列2 行记录格式
前一篇讨论了Innodb system,表空间,文件的关系及数据结构,这一篇记录下Innodb行记录的格式. 前提: 1. server层和innodb层都有自己对于record的记录格式,需要进行转 ...
- InnoDB的行记录格式, Compact, Redundant, Compressed, Dynamic
InnoDB存储引擎和大多数数据库一样(如Oracle和Microsoft SQL Server数据库),记录是以行的形式存储的.这意味着页中保存着表中一行行的数据.到MySQL 5.1时,InnoD ...
随机推荐
- VUEX报 “was assigned to but it has no setter”
如果有当前的变量(VUEX声名的)会发生改变的(change),刚绑定的值需要在data () 内进行声明 一个新的变量进行处理.
- Integer 比较忽略的问题
Integer i1 = 100; Integer i2 = 100; i1==i2Integer i3 = 199; Integer i4 = 200; i3+1 == i4int i5 = 200 ...
- EasyPR源码剖析(3):车牌定位之颜色定位
一.简介 对车牌颜色进行识别,可能大部分人首先想到的是RGB模型, 但是此处RGB模型有一定的局限性,譬如蓝色,其值是255,还需要另外两个分量都为0,不然很有可能你得到的值是白色.黄色更麻烦,它是由 ...
- 【机器学习】K均值算法(I)
K均值算法是一类非监督学习类,其可以通过观察样本的离散性来对样本进行分类. 例如,在对如下图所示的样本中进行聚类,则执行如下步骤 1:随机选取3个点作为聚类中心. 2:簇分配:遍历所有样本然后依据每个 ...
- tensorflow学习之(十一)RNN+LSTM神经网络的构造
#RNN 循环神经网络 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data tf.se ...
- java程序员随笔
之前坚持过一段时间的博客,不过后来因为一些琐事,也因为自己的懒惰,没坚持下来.一晃本科毕业到现在已经快9年了,本科毕业的时候经常想,自己十年之后会是什么样子,那时候筹措满志,心里的每一个答案,都离现在 ...
- hprose for php
1.客户端和服务器简单DEMO 通过工厂方法 create 创建客户端 $client = \Hprose\Client::create($uriList = null[, $async = true ...
- fortran常用语句--读写带注释文档、动态数组等语法
1.判断读取文档有多少行数据(文档最后的空行不计入其中): 首先在变量定义区域下方和执行语句前声明在程序中要被调用的GetFileN函数: external GetFileN 接下来在函数外部后边写上 ...
- HDU 6397 Character Encoding (组合数学 + 容斥)
题意: 析:首先很容易可以看出来使用FFT是能够做的,但是时间上一定会TLE的,可以使用公式化简,最后能够化简到最简单的模式. 其实考虑使用组合数学,如果这个 xi 没有限制,那么就是求 x1 + x ...
- 如何从本地远程访问虚拟机内的Mysql服务器?
假设重装了操作系统,则本地的很多软件可能都需要重新安装,比如数据库.但是,假设我们把一些重要的软件安装在虚拟机当中,则在重装操作系统之前,数据库服务器可以和虚拟机一起进行备份.重装操作系统之后,原先的 ...