聚簇索引与主键的选择

  • 一、什么是聚簇索引?
  • 二、什么是非聚簇索引?
  • 1. InnoDB引擎中
  • 2. MyISAM引擎中
  • 三、聚簇索引的优劣与主键选择的关系

一、什么是聚簇索引?

首先,聚簇索引不是一种单独的索引类型,其实是数据的存储方式。聚簇索引将数据存储与索引放在了一起,找到了索引也就找到了数据。

在MySql的InnoDB引擎中,表数据的文件是按照B+树组织的一个索引结构。而聚簇索引就是按照每张表的主键构造出来的B+树,叶子节点就是整张表的行数据,所以聚簇索引的叶子节点也被称为数据页。

二、什么是非聚簇索引?

1. InnoDB引擎中

主键索引就是一种聚簇索引,而其他创建出来的前缀索引、联合索引,唯一索引,都属于非聚簇索引,也称为辅助索引、二级索引。

辅助索引的叶子节点包含自身索引的键值以及聚簇索引的键(主键)。

所有辅助索引的访问都需要经过两次索引的查找:先通过非聚簇索引找到主键值,再根据主键值通过聚簇索引找到对应的行数据

有聚簇索引的表 聚簇索引 主键_mysql

2. MyISAM引擎中

在MyISAM中,索引文件与数据文件是分离的,索引文件只保存数据行的地址。主键索引与其他索引一样,都是非聚簇索引,叶子只存放数据行的地址。

有聚簇索引的表 聚簇索引 主键_有聚簇索引的表_02

三、聚簇索引的优劣与主键选择的关系

首先,由于InnoDB数据结构的关系,InnoDB其实对每张表都强制构建了聚簇索引:

  1. 有定义主键时,自动以主键构建聚簇索引
  2. 没有主键时,自动选择一个可以唯一标识数据记录的列作为主键(唯一非空索引)
  3. 以上两项都没有的时候,自动生成一个长度为6字节的长整型隐含字段作为主键,作为聚簇索引

聚簇索引的优缺点

优点

  1. 数据访问比非聚簇索引快,因为聚簇索引与数据保存在同个B+树中,比非聚簇索引少了一步寻址
  2. 聚簇索引适用于排序的场合
  3. 聚簇索引在取一个范围的数据的时候效率更高
  4. 当访问同一页数据中的不同行记录时,由于已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。如果按照主键Id来组织数据,获得数据更快

缺点:

  1. 插入的速度严重的依赖插入的顺序,按照主键顺序插入效率很高,反之将会产生页分裂,严重影响性能
  2. 由于辅助索引的存储数据,辅助索引的大小会随着主键的增大而增大
  3. 辅助索引的访问需要经过两次查找

针对以上的缺点,我们不难看出通过规范主键的值,可以规避掉这些缺点的影响:

  1. 我们一般会定义一个自增主键,保证记录按照主键顺序插入。聚簇索引的数据的物理存放顺序与索引顺序是一致的,所以只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的
  2. 我们的主键都是业务无关的,任何时候都应该杜绝修改主键,如果你的场景出现的主键的修改,说明你应该用一个新的字段存放你的原主键
  3. 分布式系统中,可以使用雪花算法,保证主键的递增而不重复

PS: 由于前端JS只能解析16位的整数,如果ID使用了大数字ID,比如雪花算法,直接返回给前端会导致16后的数字精度丢失。