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

Posted WilburXu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL InnoDB 索引组织表 & 主键作用相关的知识,希望对你有一定的参考价值。

InnoDB 索引组织表

一、索引组织表定义

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

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

条件:

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

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

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

 

二、案例

  创建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,如果为联合索引,那么久无能为力了!

 

三、为什么需要唯一主键呢?

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

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

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

  这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很高,也不会增加很多开销在维护索引上。

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

 

 

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

参考书籍:

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

 

以上是关于MySQL InnoDB 索引组织表 & 主键作用的主要内容,如果未能解决你的问题,请参考以下文章

MySQL Index--InnoDB引擎的主键索引

mysql innodb 表

mysql innodb 表

mysql索引

InnoDB关键特性之change buffer

(转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁