InnoDB存储引擎表

索引组织表

在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table)。在InnoDB存储引擎表中,每张表都有个主键(Primary Key),如果在创建表时没有显式地定义主键,则InnoDB存储引擎会按如下方式选择或创建主键:

  • 首先判断表中是否有非空的唯一索引(Unique NOT NULL),如果有,则该列即
    为主键。
    如果不符合上述条件,InnoDB存储引擎自动创建一个6字节大小的指针。
    当表中有多个非空唯一索引时,InnoDB存储引擎将选择建表时第一个定义的非空唯一索引为主键。这里需要非常注意的是,主键的选择根据的是定义索引的顺序,而不是建表时列的顺序。

InnoDB逻辑存储结构

从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区( extent)、页(page)组成。页在一些文档中有时也称为块(block )。
在这里插入图片描述

  • 表空间

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

上图中显示了表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等。因为前面已经介绍过了InnoDB存储引擎表是索引组织的( index organized),因此数据即索引,索引即数据。那么数据段即为B+树的叶子节点(图的Leaf node segment)索引段即为B+树的非索引节点(图的Non-leaf node segment)。

区是由连续页组成的空间,在任何情况下每个区的大小都为1MB。

同大多数数据库一样,InnoDB有页(Page)的概念(也可以称为块),页是InnoDB磁盘管理的最小单位。在InnoDB存储引擎中,默认每个页的大小为16KB。

在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)

InnoDB存储引擎是面向列的(row-oriented),也就说数据是按行进行存放的。

  • InnoDB行记录格式

InnoDB存储引擎和大多数数据库一样(如Oracle和 Microsoft sQL Server数据库),记录是以行的形式存储的。这意味着页中保存着表中一行行的数据。在 InnoDB 1.0.x版本之前,InnoDB存储引擎提供了Compact 和 Redundant两种格式来存放行记录数据

InnoDB数据页结构

页是InnoDB存储引擎管理数据库的最小磁盘单位。页类型为B-tree Node的页存放的即是表中行的实际数据了。
InnoDB数据页由以下7个部分组成,如图所示。
File Header (文件头)
Page Header(页头)
Infimun和 Supremum Records
User Records(用户记录,即行记录)
Free Space((空闲空间)
Page Directory (页目录)
File Trailer(文件结尾信息)
其中File Header、Page Header、File Trailer 的大小是固定的,分别为38、56、8字节,这些空间用来标记该页的一些信息,如 Checksum,数据页所在B+树索引的层数等。User Records、Free Space、Page Directory这些部分为实际的行记录存储空间,因此大小是动态的。在接下来的各小节中将具体分析各组成部分。
在这里插入图片描述

  • File Header

File Header用来记录页的一些头信息。

  • Page Header

该部分用来记录数据页的状态信息。

  • Infimum和Supremum Record

在InnoDB存储引擎中,每个数据页中有两个虚拟的行记录,用来限定记录的边界。Infimum记录是比该页中任何主键值都要小的值,Supremum指比任何可能大的值还要大的值。这两个值在页创建时被建立,并且在任何情况下不会被删除。
在这里插入图片描述

  • User Record和Free Space

User Record就是之前讨论过的部分,即实际存储行记录的内容。再次强调,InnoDB存储引擎表总是B+树索引组织的。
Free Space很明显指的就是空闲空间,同样也是个链表数据结构。在一条记录被删除后,该空间会被加入到空闲链表中。

  • Page Directory

Page Directory(页目录)中存放了记录的相对位置

  • File Trailer

为了检测页是否已经完整地写入磁盘(如可能发生的写入过程中磁盘损坏、机器关机等)

约束

  • 数据完整性
    关系型数据库系统和文件系统的一个不同点是,关系数据库本身能保证存储数据的完整性,不需要应用程序的控制,而文件系统一般需要在程序端进行控制。当前几乎所有的关系型数据库都提供了约束(constraint)机制,该机制提供了一条强大而简易的途径来保证数据库中数据的完整性。一般来说,数据完整性有以下三种形式:

实体完整性保证表中有一个主键。在 InnoDB存储引擎表中,用户可以通过定义Primary Key或Unique Key约束来保证实体的完整性。用户还可以通过编写一个触发器来保证数据完整性。

域完整性保证数据每列的值满足特定的条件。在InnoDB存储引擎表中,域完整性可以通过以下几种途径来保证:
选择合适的数据类型确保一个数据值满足特定条件。外键(Foreign Key)约束。
编写触发器。
还可以考虑用DEFAULT约束作为强制域完整性的一个方面。

参照完整性保证两张表之间的关系。InnoDB存储引擎支持外键,因此允许用户定义外键以强制参照完整性,也可以通过编写触发器以强制执行。

对于InnoDB存储引擎本身而言,提供了以下几种约束:
Primary Key
Unique Key
Foreign Key
Default
NOT NULL

  • 约束的创建和查找

约束的创建可以采用以下两种方式:
表建立时就进行约束定义
利用ALTER TABLE命令来进行创建约束

约束和索引的区别

当用户创建了一个唯一索引就创建了一个唯一的约束。但是约束和索引的概念还是有所不同的,约束更是一个逻辑的概念,用来保证数据的完整性,而索引是一个数据结构,既有逻辑上的概念,在数据库中还代表着物理存储的方式。

对错误数据的约束

在某些默认设置下,MySQL数据库允许非法的或不正确的数据的插人或更新,又或者可以在数据库内部将其转化为一个合法的值,如向NOT NULL 的字段插入一个NULL值,MySQL数据库会将其更改为0再进行插人,因此数据库本身没有对数据的正确性进行约束。

视图

在MySQL数据库中,视图(View)是一个命名的虚表,它由一个SQL查询来定义,可以当做表使用。与持久表(permanent table)不同的是,视图中的数据没有实际的物理存储。

  • 视图的作用

视图在数据库中发挥着重要的作用。视图的主要用途之一是被用做一个抽象装置,特别是对于一些应用程序,程序本身不需要关心基表(base table)的结构,只需要按照视图定义来取数据或更新数据,因此,视图同时在一定程度上起到一个安全层的作用。

分区表

MySQL数据库在5.1版本时添加了对分区的支持。分区的过程是将一个表或索引分解为多个更小、更可管理的部分。就访问数据库的应用而言,从逻辑上讲,只有一个表或一个索引,但是在物理上这个表或索引可能由数十个物理分区组成。每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理。
MySQL数据库支持的分区类型为水平分区,并不支持垂直分区。水平分区,指将同一表中不同行的记录分配到不同的物理文件中。垂直分区,指将同一表中不同列的记录分配到不同的物理文件中。

当前MySQL数据库支持以下几种类型的分区。
RANGE分区:行数据基于属于一个给定连续区间的列值被放入分区。MySQL 5.5开始支持RANGE COLUMNS的分区。
LIST分区:和 RANGE分区类型,只是LIST分区面向的是离散的值。MySQL 5.5开始支持LIST COLUMNS的分区。
HASH分区:根据用户自定义的表达式的返回值来进行分区,返回值不能为负数。
KEY分区:根据MySQL数据库提供的哈希函数来进行分区。
COLUMNS分区
在前面介绍的RANGE、LIST、HASH 和KEY这四种分区中,分区的条件是:数据必须是整型(interger),如果不是整型,那应该需要通过函数将其转化为整型,如YEAR(),TO_DAYSO),MONTH()等函数。MySQL5.5版本开始支持COLUMNS分区,可视为RANGE分区和LIST分区的一种进化。COLUMNS分区可以直接使用非整型的数据进行分区,分区根据类型直接比较而得,不需要转化为整型。

分区和性能

数据库的应用分为两类:
一类是OLTP(在线事务处理),如 Blog、电子商务、网络游戏等;
另一类是OLAP(在线分析处理),如数据仓库、数据集市。
在一个实际的应用环境中,可能既有OLTP的应用,也有OLAP的应用。如网络游戏中,玩家操作的游戏数据库应用就是OLTP 的,但是游戏厂商可能需要对游戏产生的日志进行分析,通过分析得到的结果来更好地服务于游戏,预测玩家的行为等,而这却是OLAP的应用。

对于OLAP的应用,分区的确是可以很好地提高查询的性能,因为OLAP应用大多数查询需要频繁地扫描一张很大的表。假设有一张1亿行的表,其中有一个时间戳属性列。用户的查询需要从这张表中获取一年的数据。如果按时间戳进行分区,则只需要扫描相应的分区即可。这就是前面介绍的Partition Pruning技术。

然而对于OLTP的应用,分区应该非常小心。在这种应用下,通常不可能会获取一张大表中10%的数据,大部分都是通过索引返回几条记录即可。而根据B+树索引的原理可知,对于一张大表,一般的B+树需要2~3次的磁盘IO。因此B+树可以很好地完成操作,不需要分区的帮助,并且设计不好的分区会带来严重的性能问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lhj_loveFang_1105

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值