表是什么?
就是关于特定实体地数据集合,是关系型数据库模型地核心。
索引组织表
什么是索引组织表?
表中数据都是根据主键的顺序组织存放的,这种存储方式就是索引组织表。就是存储在一个索引结构中的表。
也就是B+树的结构。
每张表都需要一个主键,如果没有定义,引擎就会去产生主键信息:
- 表中存在非空唯一索引,那么这会被指定为主键。
- 如果没有,就会由引擎创建一个主键。
InnoDB逻辑存储结构
InnoDB中所有的数据都被逻辑地放在表空间中,表空间又分为段、区、页、行。行就是存储一张表中一行的数据。
- 表空间
数据存储逻辑结构的最高处,所有的数据都放在表空间中。包括数据、索引、插入缓冲、回滚信息、系统事务信息等。 - 段
组成表空间,分为数据段、索引段、回滚段等。数据段就是B+树的叶子节点,索引段就是非叶子节点。回滚段比较特殊。 - 区
组成段空间。每个区的大小为1MB,每个区用有64个连续的页。 - 页
组成区空间。每个页默认为16K,也可以称为块。是InnoDB磁盘管理的最小单位。包括数据页、回滚页、系统页、事务数据页、插入缓冲页等。每个页最多存放7992条行。 - 行
InnoDB是面向列的,数据都是按行进程存放的。
InnoDB行记录格式
大多数存储引擎都是以行的形式存储数据的,页中存放着表中一行行的数据。
行数据的存放格式主要有:
- Caompact
- Redundant
- Compressed
- Dynamic
行溢出问题
对于一些大对象列类型的存储,可能会把数据存放在数据页之外,也就是溢出页面。
例如这样:
InnoDB页数据结构
页是存储引擎管理数据库的最小磁盘单位。
页的组成结构如图所示。
- File Header
用来存储页的信息,主要包括版本、表空间中页的偏移量、上下页等。
页还可以根据其装载的信息,分为回滚页、索引节点、插入缓冲空闲列表等很多类型。 - Page Header
用于记录数据页的状态信息。 - Infimum 和 Supremum Record
用来限定行数据的边界。
- User Record
实际的数据内容。 - Free Space
空闲列表。 - Page Directory
存放页的相对位置。用于在页中数据的行的二叉查找。 - File Trailer
用于检测页是否已经完整地写入了磁盘。做一个数据校验。
通过B+树的数据查找过程
b+树的索引结构可以定位到一个页,然后数据库将磁盘中的这一个页放到内存,再在内存中通过Page Directory进行二叉查找,准确定位到一条行数据。
约束
什么是约束?
是一种机制,提供强大而简易地途径来保证数据库中数据地完整性。比如某个数据不能是空,某类型数据不能重复等等。
数据完整性
数据完整性有以下三种形式:
- 实体完整性
保证表中具有一个主键。 - 域完整性
保证每列值满足特定条件。外键约束和编写触发器来保证。 - 参照完整性
保证两张表之间的关系。外键约束和编写触发器来保证。
InnoDB提供了几种约束:
- 主键
- 唯一索引键
- 外键
- Default
- NOT NULL
主键和唯一索引键的区别:
- 主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
- 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
- 唯一性索引列允许空值,而主键列不允许为空值。
- 主键列在创建时,已经默认为非空值 + 唯一索引了。
- 主键可以被其他表引用为外键,而唯一索引不能。
- 一个表最多只能创建一个主键,但可以创建多个唯一索引。
- 主键和唯一索引都可以有多列。
- 主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。
- 在 RBO 模式下,主键的执行计划优先级要高于唯一索引。 两者可以提高查询的速度。
约束的创建和查找
创建可以采用两种方式:
- 建立表式就进行约束定义。
- 利用ALTER TABLE命令来创建约束。
约束和索引的区别
当用户创建了一个唯一索引,就创建了一个唯一的约束。但是二者概念不同,约束是逻辑概念,是保证数据完整的,索引是一个数据结构。
也就是说,约束是索引可能的一种结构。
触发器约束
触发器就是一个程序,在实现修改数据命令之前或者之后自动调用。用来预防违法的数据库修改命令。
比如某个数据不能递减,某个修改操作将其递减了,那就可以设置触发器逻辑,如果检测到错误SQL逻辑,就将值变为原来的,再将这个错误写到日志中。
外键约束
什么是外键?
引用其他表的键对,就是外键。是用于建立和加强两个表数据之间的链接的一列或多列。通过将保存表中主键值的一列或多列添加到另一个表中,可创建两个表之间的链接。这个列就成为第二个表的外键。这样同时使用两张表,就能保证数据的完整。
比如我要向工资表中插入一个员工的工资,但是这个员工必须存在于员工信息表中,不然就不能确认是不是真的存在这个员工,每次插入操作都去查是不是有这个员工,那么就能保证数据的完整性。
视图
什么是视图?
是一个命名的虚表,由一个SQL查询来定义,可以当作表使用,与正常的表的区别就是没有真的数据。
视图的作用
- 通过视图,可以展现基表的部分数据;
- 视图数据来自定义视图的查询中使用的表,使用视图动态生成。
- 基表:用来创建视图的表叫做基表
说白了,就是将一个或者多个表融合,产生一种新的组合的或者部分的数据。让程序员看到想要的那些数据。
物化视图
物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的。普通视图是虚拟表,应用的局限性大,任何对视图的查询, Oracle 都实际上转换为视图SQL语句的查询。这样对整体查询性能的提高,并没有实质上的好处。
而物化视图是一张实际存在的表,是占有数据库磁盘空间的。
物化视图并不像普通视图那样,只有在使用的时候才去读取数据,而是预先计算并保存表连接或者聚集等比较耗时操作的结果,这样大大提高了读取的速度,特别适合抽取大数据量表的某些信息。
分区表
什么是分区?
就是将一个表或者索引分为多个更小的可管理的部分。这样就便于管理。
分区的类型
- 水平分区:对表的行进行分区,不同分组中物理分隔的数据组合在一起,表中的所有列都可以在每个分区找到,维持了表的属性结构。
- 垂直分区:把某些特定的列划分到特定的分区,减少表的宽度,每个分区都保存了其中列所在的行。
MySQL支持的分区类型
- 区间分区:将不同区间的数据行分到不同表。
- 列表分区:离散的数据行进行分区。
- 哈希分区:用户自定义的表达式进行分区。
- 键分区:数据库提供的哈希函数进行分区。
分区的性能
不是分区就能提高数据的性能。
要根据不同事务来确定分区策略:
- OLTP 在线事务处理,如电子商务和游戏
分区可以提高性能,因为这类事务需要扫描一张很大的表,分区可以减少扫面时间。 - OLAP 在线分析处理,如数据仓库
这种事务不太可能需要经常获取一张表的很多数据,通常只要返回几条数据,所以,利用B+树就能很好地完成操作,分区不好就会降低性能。
总结
我认为本章的重点在于:
- B+树在表结构中的作用方式。
- 约束中的各种键。
- 分区性能。
为什么我们需要了解InnoDB地内部逻辑?这对之后理解索引、事务和性能调优都有很大地帮助。