MySQL InnoDB 索引组织表 & 主键做用

InnoDB 索引组织表缓存

1、索引组织表定义安全

在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)。优化

在InnoDB存储引擎中,每张表都有个主键(Primary key),若是在建立表时没有地定义主键,则InnoDB存储引擎会选择表中符合条件的列去建立主键spa

条件:设计

1.  首先判断表中是否有非空的惟一索引(Unique NOT NULL),若是有,则该列即为主键。指针

2. 若是不符合上述条件,InnoDB存储引擎自动建立一个6字节大小的指针。code

当表中存在多个非空的惟一索引的时候,InnoDB存储引擎会根据建表时所建立的第一个非空惟一索引做为主键。blog

 

2、案例索引

  建立test表内存

CREATE TABLE test(
    a INT NOT NULL ,
    b INT NULL ,
    c INT NOT NULL ,
    d INT NOT NULL ,
    UNIQUE KEY(b) ,
    UNIQUE KEY(d) ,
    UNIQUE KEY(c)
)

 

  初始化数据

INSERT INTO test SELECT 1,2,3,4;
INSERT INTO test SELECT 5,6,7,8;

 

  经过如下语句能够判断表带主键值(_rowid为主键)

select *,_rowid from test;

  虽然b字段索引的顺序在d以前,但因为b字段容许空值,因此依次往下排即选取d字段为主键。

  ps,若是为联合索引,那么久无能为力了!

 

3、为何须要惟一主键呢?

主键(primary key) 一列(或一组列),其值可以惟一区分表中的每一个行。 惟一标识表中每行的这个列(或这组列)称为主键。没有主键,更新或删除表中特定行很困难,由于没有安全的方法保证只设计相关的行。简单的说主键的目的在于索引。

InnoDB引擎使用汇集索引,数据记录自己被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,所以每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,若是页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)。

1. 若是表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。以下图所示:

  这样就会造成一个紧凑的索引结构,近似顺序填满。因为每次插入时也不须要移动已有数据,所以效率很高,也不会增长不少开销在维护索引上。

2.  若是使用非自增主键若是身份证号或学号等),因为每次插入主键的值近似于随机,所以每次新纪录都要被插到现有索引页得中间。此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增长了不少开销,同时频繁的移动、分页操做形成了大量的碎片,获得了不够紧凑的索引结构,后续不得不经过OPTIMIZE TABLE来重建表并优化填充页面。

 

 

如有不恰当之处,还望指教,谢谢!

参考书籍:

[1]. MySQL技术内幕:InnoDB存储引擎

相关文章
相关标签/搜索