1. InnoDB索引组织表
在InnoDB存储引擎表中,每张表都有个主键,如果在创建表时没有显式地定义主键,则InnoDB存储引擎会按如下方式选择或创建主键:
- 首先表中是否有非空的唯一索引,如果有,则该列即为主键。
- 不符合上述条件,InnoDB存储引擎自动创建一个6字节大小的指针。
2. InnoDB逻辑存储结构:
所有数据都被逻辑地存放在一个空间中,我们称之为表空间。表空间又由段(segment)、区(extent)、页(page)组成,页有时也称为块。
表空间:
- 表空间可看做是InnoDB存储引擎逻辑结构的最高层,所有的数据都是存放在表空间中。
- 默认情况下InnoDB有一个共享表空间ibdata1,即所有数据都放在这个表空间内,如果启用参数innodb_file_per_table,则每张表内的数据可以单独放到一个表空间内。
- 在启用参数后,需要注意的是:每张表的表空间内存放的只是数据、索引和插入缓冲,其他类的数据,如撤销信息、系统事务信息、二次写缓冲等还是放在原来的共享表空间内。
段:
- 表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等。
- 前面介绍过InnoDB存储引擎表是由索引组织的,因此数据即索引,索引即数据。那么数据段即为B+树的页节点(图中的leaf node segment),索引段即为B+树的非索引节点(none-leaf node segment)。
- 注意并不是每个对象都有段。因此更准确的说,表空间是由分散的页和段组成。
区:
- 区是由64个连续的页组成的,每个页大小为16KB,即每个区大小为1MB。
- 对于大的数据段,InnoDB存储引擎最多每次可以申请4个区,以此来保证数据的顺序性能。
- 在每个段开始时,先有32个页大小的碎片页来存放数据,当这些页使用完之后才是64个连续页的申请。
页:
- 页是InnoDB磁盘管理的最小单位。
- 常见页类型有:数据页、Undo页、系统页、事务数据页、插入缓冲位图页、插入缓冲空闲列表页、未压缩的二进制大对象页、压缩的二进制大对象页。
行:
- InnoDB存储引擎是面向行的,也就是说数据的存放按行进行存放。每个页最多存放7992行记录。
3. InnoDB物理存储结构 :
物理意义上,InnoDB表由共享表空间、日志文件组和表结构定义文件组成。
InnoDB行记录格式:
Compact行记录格式:(MySQL5.0开始被引入的)
设计目标是能高效存放数据。简单来说,如果一个页中存放的行数据越多,其性能就越高。
4. 约束
1数据完整性
关系型数据库与文件系统的一个不同点是,关系数据库本身能保证存储数据的完整性,不需要应用程序的控制,而文件系统一般需要在程序端进行控制。几乎所有的关系型数据库都提供了约束机制,约束提供了一条强大而简易的途径来保证数据库中的数据完整性,数据完整性有三种形式:
- 实体完整性
- 保证表中有一个主键。在innodb存储引擎表中,我们可以通过定义Primary key或Unique key约束来保证实体的完整性。或者我们还可以通过编写触发器来保证数据完整性。
- 域完整性
- 保证数据的值满足特定的条件。在innodb中,域完整性可通过以下途径来保证:选择合适的数据类型可以确保一个数据值满足特定条件,外键约束,编写触发器。还可以考虑用default约束作为强制域完整性的一个方面。
- 参照完整性
- 保证两张表之间的关系。InnoDB支持外键,因此允许用户定义外键以强制参照完整性,也可以编写触发器强制执行。
对于InnoDB,提供了4种约束:
- Primary Key(主键)
- Unique key
- Foreign Key(外键)
- Default
- Not null
2约束和索引的区别:
当你创建了一个唯一索引,就创建了一个唯一的约束。但是约束和索引的概念还是有所不同的,约束更是一个逻辑的概念,用来保证数据的完整性,而索引是一个数据结构,有逻辑上的概念,在数据库中更是一个物理存储的方式。
3触发器与约束:
触发器的作用是在insert、delete和update命令之前或之后自动调用sql命令或者存储过程。
创建触发器命令:create trigger
最多可以为一个表建立6个触发器,分别为insert、update、delete的before和after各定义一个。(before和after代表触发器发生的时间,表示是在每行操作的之前发生还是之后发生)
4视图:
视图(View)是一个命名的虚表,它由一个查询来定义,可以当作表使用。与持久表不同的是,视图中的数据没有物理表现形式。
视图的主要用途之一是被用作一个抽象装置。程序本身不用关心基表的结构,只需要按照视图定义来获取数据或更新数据。因此,视图同时在一定程度上起到一个安全层的作用。
create view v_t as select * from t where id<10;