Mysql技术内幕InnoDB存储引擎读书笔记--《四》表

来源:互联网 发布:施华蔻黑胶和银胶 知乎 编辑:程序博客网 时间:2024/06/05 17:08

4.1InnoDB存储引擎表类型

如果在创建表时没有显示地定义主键,那么InnoDB存储疫情会按照如下方式选择或者创建主键。

  • 首先表中是否有非空的唯一索引,如果有,则该列即为主键
  • 不符合上述条件,InnoDB存储疫情自动创建一个6个字节大小的指针

4.2InnoDB逻辑存储结构

InnoDB存储引擎的所有数据都被逻辑地存放在表空间中。表空间又由段(segment)、区(extent)、页(page)组成。

4.2.1表空间

默认情况下InnoDB存储引擎有一个共享表空间ibdata1,即所有数据都放在这个表空间内。如果我们启用了参数innodb_file_per_table,则每张表内的数据可以单独放到一个表空间内。

对于启用了innodb_file_per_table参数选项,每张表的表空间内存放的只是数据、索引和插入缓冲,其他类的数据,如撤销(Undo)信息、系统事务信息、二次写缓冲等还是存放在原来的共享表空间内。

4.2.2段

表空间是由分散的页和段组成。

4.2.3区

区是由64个连续的页组成,即每个区的大小为1MB。对于大的数据段,InnoDB存储引擎最多每次可以申请4个区,以此来保证数据的顺序性能。

4.2.4页

InnoDB的页的大小为16KB。

4.2.5行

InnoDB存储引擎是面向行的,也就是说数据的存放按行进行存放。每个页存放的行记录也是有硬性定义的,最多允许存放16KB/2~200行的记录,即7992行记录。

4.3InnoDB物理存储结构

从物理意义上来看,InnoDB表由共享表空间、日志文件组(更准确地说,应该是Redo文件组)、表结构定义文件组成。若将innodb_file_per_table设置为on,则每个表将独立地产生一个表空间文件,以idb结尾,数据、索引、表的内部数据字典信息都将保存在这个单独的表空间文件中。表结构定义文件以frm结尾。这个是以与存储引擎无关的,任何存储引擎的表结构定义文件都一样,为.frm文件。

4.4InnoDB行记录格式

4.4.1Compact行记录格式

Compact行设计目标是能高效存放数据。简单来说,如果一个页中存放的行数据越多,其性能就越高。

变长字段长度列表 NULL标志位 记录头信息 列1数据 列2数据 ……

Compact行格式的首部是一个非NULL变长字段长度列表,而且是按照列的顺序逆置放置的。当列的长度小于255字节,用1字节表示,若大于255个字节,用2个字节表示,变长字段的长度最大不可以超过2个字节。第二个部分是NULL标志位,该位知识了该行数据中是否有NULL值,用1表示。该部分所占的字节应该为bytyes。接下去的部分是记录头信息,固定占用5个字节。最后的部分就是实际存储的每个列的数据,需要特别注意的是,NULL值不占该部分任何数据,即NULL除了战友NULL标志位,还有两个隐藏列,事务ID列和回滚指针列,分别为6个字节和7个字节的大小。若InnoDB没有定义Primary Key,每行会增加一个6字节的RowId列。

由此可以算出Mysql的varchar最大长度为65532个字节,65535-1(NULL标志)-2(变长字段)=65532。

Redundant行记录格式

Redundant是Mysql5.0之前的,不过多介绍。

4.4.3行溢出数据

对于大多数的情况,BLOB的行数据还是会发生行溢出,实际数据保存在BLOB页中,数据页只保存数据的前768个字节。

4.4.5char的行结构存储

在InnoDB引擎内部对于char类型在多字节字符集类型(如utf8)的存储,char很明确的被视为了变长类型,对于未能占满长度的字符还是填充长度。可以说,在多字节字符集的情况下,char和varchar的行存储基本是没有区别的。

4.5InnoDB数据页结构

InnoDB数据页由以下七个部分组成:

File Header Page Header Infimum+Supremum Records User Records Free Space Page Directory File Trailer

4.5.1File Header

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

  • FILE_PAGE_SPACE_OR_CHKSUM,该值代表页的checksum值。
  • FIL_PAGE_OFFSET:表空间中页的偏移值。
  • FIL_PAGE_PREV,FIL_PAGE_NEXT:当前页的上一个页以及下一个页。B+ Tree特性据定了叶子节点必须是双向列表。
  • FIL_PAGE_LSN:该值代表该页最后被修改的日志序列位置LSN(Log Sequence Nuber)。
  • FIL_PAGE_TYPE:页的类型,通常有:B+树页节点,Undo Log页,索引节点,Insert Buffer空闲列表,该页为最新分配,Insert Buffer位图这几种意思。
  • FIL_PAGE_FILE_FLUSH_LSG:该值仅在数据文件中的一个页中定义,代表文件至少被更新到了该LSN值。
  • FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID:该值代表页面属于哪个表空间。

4.5.2Page Header

  • PAGE_N_DIR_SLOTS:在Page Directory(页目录)中的Slot(槽)数。
  • PAGE_HEAP_TOP:堆中第一个记录的指针。
  • PAGE_N_HEAP:堆中的记录数。
  • PAGE_FREE:指向空闲列表的首指针。
  • PAGE_GARBAGE:已删除记录的字节数,即行记录结构中,delete flag为1的记录大小的总数。
  • PAGE_LAST_INSERT:最后插入记录的位置。
  • PAGE_DIRECTION:最后插入的方向。
  • PAGE_N_DIRECTION:宇哥方向连续插入记录的数量。
  • PAGE_N_RECS:该页中记录的数量。
  • PAGE_MAX_TRX_ID:修改当前页的最大事务ID,注意该值仅在Secondary Index定义。
  • PAGE_LEVEL:当前页在索引树中的位置,0x00代表叶节点。
  • PAGE_IDNEX_ID:当前页属于哪个索引ID。
  • PAGE_BTR_SEG_LEAF:B+树的叶节点中,文件段的首指针位置。注意该值仅在B+树的Root页中定义。
  • PAGE_BTR_SEG_TOP:B+树的非叶节点中,文件段的首指针位置。注意该值仅在B+树的Root页中定义。

4.5.3Infimum和Supremum记录

在InnoDB存储引擎中,每个数据页中有两个虚拟的行记录,用来限定记录的边界。Supremum和Infimum分别是主键值得上界和下界,这两个值在页创建时被建立,并且在任何情况下不会被删除。

4.5.4User Records与FreeSpace

User Records就是之前我们讨论过的部分,即实际存储行记录的内容。
Free Space指的就是空闲空间,同样也是个链表数据结构。当一条记录被删除后,该空间会被加入空闲链表中。

4.5.5Page Directory

Page Directory(页目录)中存放了记录的相对位置。需要记住,B+树索引本身并不能找到具体的一条记录,B+树索引能找到的只是该记录所在的页。数据库把页载入内存,然后通过Page Directory再进行二分查找。

4.5.6File Trailer

用来保证页能够完整的写入磁盘,来作比较以此来保证页的完整性。

4.7约束

外键

一般来说,我们称被引用的表为父表,另一个引用的表为子表。外键定义为:ON DELETE和ON UPDATE表示父表做DELTE和UPDATE操作时相应的子表所做的操作。可定义子表操作有:

  • CASCADE:当父表发生DELETE或UPDATE操作时,相应的子表中的数据也进行同样操作。
  • SET NULL:当父表发生DELETE或UPDATE操作时,相应的子表中的数据被设置为NULL值。当然,子表中的相应的列必须允许NULL值。
  • NO ACTION:当父表发生DELETE或UPDATE操作时,剖出错误,不允许这类操作发生。*如果定义外键时没有指定ON DELETE或ON UPDATE,这就是默认的外键设置。

4.8视图

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

Mysql本身不支持物化视图,需要采用SELECT然后INSERT类似这种的方式导入视图的数据到表中。

4.9分区

Mysql分区实际上就是将一张表的数据分成多个部分,如果对于大的数据量,分区让我们可以快速定位数据位于那一部分,那么就直接排除掉了其他部分的数据,所以分区有利于查询性能。

查询未添加索引的列,分区比未分区的表快很多倍;查询已添加索引的列,分区稍由于未分区的表。

分区可参考该文章:深入解析MySQL分区(Partition)功能。

阅读全文
0 0
原创粉丝点击