日期:2014-05-16  浏览次数:20480 次

MySQL技术内幕:InnoDB存储引擎读书笔记(中)

第四章、表

  4.1、innodb存储引擎表类型

  innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示的定义主键则innodb如按照如下方式选择或者创建主键。

  首先表中是否有唯一非空索引(unique not null),如果有则该列即为主键。

  不符合上述条件,innodb存储引擎会自动创建一个6字节大小的指针,rowid().

  4.2、innodb逻辑存储结构

  innodb的逻辑存储单元由大到小分别是 tablespace,segment,extent,page(block)组成。

  4.2.1、表空间(tablespace)

  大部分内容和3.6.1章节相同,可以通过产生undo操作来验证共享表空间存储undo的信息,也可以通过py_innodb_page_info.py来查看表空间文件中各页的类型和数量。

  4.2.2、段(segment)

  常见的segment有数据段、索引段、回滚段。

  由于我们刚才说过,innodb是索引聚集表,所以数据就是索引,索引就是数据,那么数据段即是B+树的页节点(leaf node segment),索引段即为B+树的非索引节点(non-leaf node segment).innodb的segment是innodb自动完成的,不许要人工参与。

  4.2.3、区(extend)

  区是由64个连续的页主成,每个页大小为16K,即每个区的大小为(64*16K)=1MB,对于大的数据段,mysql每次最多可以申请4个区,以此保证数据的顺序性能。

  对于innodb_file_per_table参数的特殊情况,开启这个参数后,默认创建的表空间大小为96K。 区是64个连续的页,应该创建1M才对啊?原因就是每个段开始时有32个页大小的碎片页(fragment page)来存放数据,当这些页使用完成以后,才是32+64个连续页的申请。具体参见P75的实验。

  4.2.4、页(page)

  页是innodb磁盘管理最小的单位,innodb每个页的大小是16K。常见的页类型有:

  数据页 B-tree Node

  undo页 Undo Log Page

  系统页 System Page

  事务数据页 Transaction system Page

  插入缓冲位图页 Insert Buffer Bitmap

  插入缓冲空闲列表页 Insert Buffer free Bitmap

  未压缩的二进制大对象页 Uncompressed BLOB Page

  压缩的二进制大对象页 Compressed BLOB Page

  4.2.5、行

  innodb存储引擎是面向行的(row-oriented),也就是说数据的存放按行进行存放。每个页最多可以存放16K/2~200行,也就是8192和81.92个行。

  也有面向列的数据库(column-orientied), mysql infobright就是面向列的,对于数据仓库下的分析类sql语句和数据压缩很有好处。

  4.3、innodb物理存储结构

  innodb引擎由共享表空间,日志文件(redo log),表结构定义文件组成。如果开启了innodb_file_per_table,那每个表将独立的产生一个表空间文件,以ibd结尾,数据、索引、表的内部数据字典都将被保存在这个单独的表空间中。

  4.4、innodb行记录格式

  mysql从5.1开始,innodb提供了compact和redundant(为了兼容以前版本)两种格式来存放行记录数据。可以通过show table status like t\G来查看格式。

  4.4.1、compact行记录格式

  P85

  4.4.2、redundant行记录格式

  P88

  4.4.3、行溢出数据

  varchar(N)最多可以存储多少个字符跟表的字符集格式有关系,在latin1下,varchar可以存储65532个字符,在GBK下可以存储32767个字符,和UTF8下可以存储21845个字符。使用?varchar 提示的0-65535指的是字节。

  一个页是16K,如何存储65535字节呢?这个时候就会出现行溢出,在B-tree节点页存储768字节的前缀,剩下的数据存入Uncompressed BLOG Page。为什么会在B-tree节点页存储768个字节,而不全部存进去呢?因为innodb是索引组织表(B-tree),一个页中至少应该有2条记录,否则就成链表,失去了B+树的意义。所以innodb会自我优化,一个页中如果只能存放一条记录,那么innodb存储引擎会自动将数据存储到溢出页。

  4.4.4、compressed与dynamic记录格式

  P98

  4.4.5、char的行结构存储

  从mysql4.1开始CHR(n),中N指定的是字符的长度,而不是之前版本的字节长度。也就是说在不同字符集下,CHAR的内部存储不是定长的数据。可以通过select a,char_length(a),length(a) from t;查看字符和字节数。所以在多字符集下,char和varchar占用a空间是一样的。

  4.5、innodb数据页结构

  P101

  4.6、named file formats

  innodb存储引擎通过named file formats机制来解决不同版本下页结构兼容性问题。

  4.7、约束

  4.7.1、数据完成行

  innodb提供了以下四种约束

  Primary key

  Unique Key

  Foreign Key

  Default

  Not NULL

  4.7.2、约束的创建和查找

  创建时候定义,或者使用alter table定义。

  4.7.3、约束和索引的区别

  primary key和unique key既是约束也是主键。约束是一个逻辑的概念,用来保证数据完整性,而索引是一个数据结构,有逻辑上的概