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实例的方 ...
随机推荐
- [转帖]深度硬核文:Nginx的301重定向处理过程分析
https://zhuanlan.zhihu.com/p/84539204 本文首发于公众号:js-mindmap 一,序言 "晚上九点,办公室里烟雾缭绕,工作进度依然没有什么进展.王二胖打 ...
- [转帖]大模型训练,英伟达Turing、Ampere和Hopper算力分析
https://www.eet-china.com/mp/a219195.html 大 GPU 优势在于通过并行计算实现大量重复性计算.GPGPU即通用GPU,能够帮助 CPU 进行非图形相关程序的运 ...
- [转帖]关于Linux操作系统中LUN的队列深度(queue_depth)
Linux中的queue_depth(队列深度),可以用lsscsi查看. 不过今天在我的vm 虚拟机环境中(无外界存储),是没有lsscsi命令. 不过,从网上,搜到了如下的信息: $ lsscsi ...
- 最小化安装的CentOS7 上面安装Oracle12C的简单过程
首先声明自己对静默安装不熟,也害怕初问题,所以不使用静默安装的方式. 因为是最小化安装,所以必须安装GUI界面才可以,以下是过程(早上回忆的,全文字,无截图) 1. 安装GUI界面 yum group ...
- vue中keep-alive详细讲解
场景 今天产品跑过来跟我说, 当我在A页面修改数据后,去B页面. 然后返回A页面.希望A页面保留我修改后的数据. 而不是数据又恢复最初的样子了.我心里想,尼玛,又要加班了? 看下面小粒子 数据被被重置 ...
- vm-storage在全部都是旧metric情况下的写入性能测试
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 接上篇:测试所有metric都是存在过的metric的情况 ...
- 【K哥爬虫普法】百度、360八年恩怨情仇,robots 协议之战终落幕
我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识,知 ...
- JS ----- JS原型与原型链终极详解(一)
一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object .Function 是 JS 自带的函数对象.下面举例说明 var o1 = ...
- 6张图表 + 1个案例 带你入门tcpdump的使用和原理
一.tcpdump简介 tcpdump是什么? 来看看 tcpdump官网怎么说:This is the home web site of tcpdump, a powerful command-li ...
- 1.13 导出表劫持ShellCode加载
在Windows操作系统中,动态链接库DLL是一种可重用的代码库,它允许多个程序共享同一份代码,从而节省系统资源.在程序运行时,如果需要使用某个库中的函数或变量,就会通过链接库来实现.而在Window ...