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来重建表并优化填充页面。

原文地址:https://www.cnblogs.com/wilburxu/p/9419275.html

时间: 2024-10-10 12:08:51

MySQL InnoDB 索引组织表 & 主键作用的相关文章

mysql测试索引在表中的作用

实验内容 单表中的索引使用 1.建表 create table t_book(id int,a1 varchar(200),a2 varchar(200),a3 varchar(200),a4 varchar(200),a5 varchar(200),a6 varchar(200),a7 varchar(200),a8 varchar(200),a9 varchar(200)) 2.写存储过程向表中插入较大数据//或其他方式使数据增大 (1)绑定变量: PREPARE stmt1 FROM 'i

【Todo】聚集索引、非聚集索引、聚集索引组织表、堆组织表、InnoDB、MyISAM等的学习

参考: http://www.jb51.net/article/76007.htm http://blog.csdn.net/xqy1522/article/details/6750252 下面是第一篇的总结: 在MySQL中,InnoDB引擎表是(聚集)索引组织表(clustered index organize table),而MyISAM引擎表则是堆组织表(heap organize table). 聚集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序: 而非聚集索引

删除指定表的所有索引,包括主键索引,唯一索引和普通索引 ,适用于sql server 2005,

原文:删除指定表的所有索引,包括主键索引,唯一索引和普通索引 ,适用于sql server 2005, --删除指定表中所有索引 --用法:declare @tableName varchar(100) --set @tableName='表名' --表名 ,根据实际情况替换 --exec sp_dropindex @tableName if exists(select 1 from sysobjects where id = object_id('dropindex') and xtype =

mysql 表主键类型由int 改为bigint

需求:由于业务的需要,tmp_employees的emp_no主键字段类型为int已经不能满足业务的需求,此时需要将该表主键字段类型由int 更改为 bigint 使用工具:pt-online-schema-change ./pt-online-schema-change  --user=root --password=root456 --recursion-method="processlist" --alter="modify column emp_no bigint n

堆表 索引组织表

堆表 : 堆就是无序数据的集合,索引就是将数据变得有序,在索引中键值有序,数据还是无序的 数据存放在数据里面,索引存放在索引里 堆表中,主键索引和普通索引一样的,叶子节点存放的是指向堆表中数据的指针(可以是一个页编号加偏移量),指向物理地址,没有回表的说法 堆表中,主键和普通索引基本上没区别,和非空的唯一索引没区别 mysql 的 myisam 引擎,oracle pg 都支持的是堆表 索引组织表: innodb 引擎支持的就是索引组织表 对于主键的索引,页子节点存放了一整行所有数据,其他索引称

Mybatis框架(9)---Mybatis自定义插件生成雪花ID做为表主键项目

Mybatis自定义插件生成雪花ID做为主键项目 先附上项目项目GitHub地址 spring-boot-mybatis-interceptor 有关Mybatis雪花ID主键插件前面写了两篇博客作为该项目落地的铺垫. 1.Mybatis框架---Mybatis插件原理 2.java算法---静态内部类实现雪花算法 该插件项目可以直接运用于实际开发中,作为分布式数据库表主键ID使用. 一.项目概述 1.项目背景 在生成表主键ID时,我们可以考虑主键自增 或者 UUID,但它们都有很明显的缺点 主

索引组织表

select * from aa where id=1; 如果在id列建立索引,那么他会首先在索引块中找到该记录的rowid,然后再进行回表读, 如果要查询索引以外的列,那么回表读是不可避免的. 但是建立索引组织表就可以避免回表读 试验 索引组织表的最大特点就是表就是索引,索引就是表,这个一种特别的设计,所以不用访问表 不过这种表的开销要比普通表的开销大. 因为表要和索引一样要有序的排列,更新负担会很严重,因此这种设计一般使用在更新很少,频繁读的的应用场合 比如地区配置表,这种表数据一般很少变动

mycat分布式mysql中间件(自增主键)

一.全局序列号 全局序列号是MyCAT提供的一个新功能,为了实现分库分表情况下,表的主键是全局唯一,而默认的MySQL的自增长主键无法满足这个要求.全局序列号的语法符合标准SQL规范,其格式为:next value for MYCATSEQ_XXXMYCATSEQ_XXX 是序列号的名字,MyCAT自动创建新的序列号,免去了开发的复杂度,另外,MyCAT也提供了一个全局的序列号,名称为:MYCATSEQ_GLOBAL 注意,MYCATSEQ_必须大写才能正确识别.MyCAT温馨提示:实践中,建议

Oracle 11g笔记——索引组织表

一.索引组织表(Index-Organized Table, IOT) 索引组织表是一类特殊的表,它将索引和表的数据存储在一起.普通表的数据以无序(Heap)的方式存放在数据库中. 而索引组织表按照主键进行排序,以二叉树的形式对表的数据进行存储. 索引组织表不存储ROWID,它通过主键来访问数据. 索引组织表适合通过主键对数据进行访问的应用. 1.优点 (1)快速的随机访问.索引和表的数据存储在一起,如果对表进行更新,Oracle只更新索引结构. (2)快速的范围扫描.索引组织表已经按照主键对数