MysqL 主键索引 就是 聚簇索引 吗

文章目录



1

在 MySQL 默认的 InnoDB 存储引擎 中,

给字段 设置 主键约束 的同时,就会自动创建对应的主键索引(聚簇索引),完全不需要你手动额外去建。


一、为什么是自动的?

InnoDB 的表是「索引组织表」------整张表的所有数据,本身就是按照主键排序,存储在主键索引(聚簇索引)的 B+ 树叶子节点里。

可以理解为:主键索引就是表本身,没有它,数据都没地方存

所以:

  • 你设置 PRIMARY KEY 约束,本质是同时做了两件事:
    1. 加上「非空 + 唯一」的数据约束
    2. 自动生成对应的主键聚簇索引

SHOW INDEX FROM employees; 查询结果中,那个名字固定叫 PRIMARY 的索引,就是设置主键时自动生成的。


二、延伸:如果不设主键会怎样?

如果一张表你没主动设主键,InnoDB 也会偷偷生成聚簇索引来组织数据,优先级是:

  1. 优先选第一个 唯一且非空 的字段,当作聚簇索引
  2. 如果连唯一非空字段都没有,InnoDB 会内部生成一个隐藏的 6 字节 ROW_ID 字段,用它来建聚簇索引

但这种隐藏索引对你不可见,也没法用来优化查询,所以开发中每张表都建议主动设自增主键


补充小结论

  • 建主键 = 自动有主键索引
  • 删主键 = 主键索引跟着一起删掉
  • 日常开发中,永远不要给主键字段再单独建索引

一、为什么设置主键,就会自动创建主键索引?

核心原因:InnoDB 的表,天生就是「索引组织表」,数据必须依附索引才能存在

你可以这么理解:

  • 像 MyISAM 这类老引擎,是"先有数据文件,再单独建索引文件",索引和数据是分开的两个文件。
  • 但 InnoDB 不一样,它整张表的所有行数据,本身就是按照主键的顺序,存储在一棵 B+ 树的叶子节点里。这棵 B+ 树,既是存放数据的容器,也是主键索引本身

当你给字段加 PRIMARY KEY 约束时,MySQL 其实同时做了两件事:

  1. 加数据约束:保证这个字段非空、不重复,作为每行数据的唯一标识。
  2. 建物理存储结构 :把整张表的数据,按这个主键字段排序,组织成一棵 B+ 树------这棵树,就是主键索引

换句话说:

对 InnoDB 来说,

不是 "先有表,再额外建个主键索引",

而是 "表本身 就是按 主键索引 存的",没有主键索引,数据都没地方放。

所以,设置主键的同时,主键索引必然自动生成,这是存储结构决定的,不是可选操作。


二、主键索引就是聚簇索引吗?

在 InnoDB 里,只要表有主键,那么「主键索引」和「聚簇索引」就是同一个东西的两个不同名字,只是命名角度不一样。

主键索引(聚簇索引):(聚簇索引)就是补充说明它的物理属性:这个主键索引,它的存储形态是聚簇索引。

两个名字的区别

名称 命名角度 核心含义
主键索引 功能 / 约束维度 基于主键字段建立的索引,作用:唯一标识行、加速主键查询
聚簇索引 物理存储维度 叶子节点直接存放完整行数据,数据 和 索引 "聚集在一起"的索引结构

打个通俗的比方:

  • 同一个人,在公司叫"张工程师"(职位/功能角度),在家里叫"小张"(家庭身份角度)。人是同一个,只是称呼的视角不同。
  • 同一个 B+ 树,从"它是主键字段的索引"角度,叫主键索引;从"它叶子节点存了完整数据、数据和索引聚在一起"的物理结构角度,叫聚簇索引。

补充:不是所有情况,聚簇索引 都等于 主键索引

聚簇索引是 InnoDB 必须有的结构,但它不一定非得是主键:

  1. 表有主键 → 主键自动成为聚簇索引(99% 的业务场景都是这样)
  2. 表没主键,但有唯一非空索引 → 第一个唯一非空字段会被当作聚簇索引
  3. 表既没主键也没唯一非空索引 → InnoDB 内部偷偷生成一个隐藏的 6 字节 ROW_ID,用它来做聚簇索引

但这种隐藏的聚簇索引对你不可见,也没法用来优化查询,所以开发中永远建议主动设置自增主键。


回表

  • 二级索引(普通索引、唯一索引)的叶子节点只存"索引值 + 主键值"
  • 查询时拿到主键后,需要再去聚簇索引(也就是主键索引) 里查完整的行数据
  • 这个二次查找的过程,就是回表

因为,聚簇索引就是主键索引那棵树,

所以,"回表"本质就是:从二级索引树,回到主键索引树去找完整数据。

相关推荐
Blossom i3 小时前
大数据预处理与采集实验一:使用Python操作MySQL数据库
数据库·mysql
InfinitePlus4 小时前
Docker MySQL搭建一主一从
mysql·docker
坐吃山猪6 小时前
Docker07-MySQL
mysql·docker·容器
少晓年7 小时前
从 MySQL 迁移到人大金仓 KingbaseES:完整指南与实践
数据库·mysql
Zhu7588 小时前
使用helm在k8s集群部署MySQL单实例,支持当前所有主版本的最新子版本
mysql·adb·kubernetes
灯澜忆梦12 小时前
【MySQL11】进阶篇 | 索引_#3使用规则
数据库·sql·mysql·性能优化
wWYy.12 小时前
Mysql:有哪些锁?
数据库·mysql
hey_sml13 小时前
MySQL常用操作速记:从字符集到游标全解析
java·开发语言·mysql
云技纵横13 小时前
线上接口突然超时,怎么判断卡在 Nginx、线程池、连接池还是 SQL?
后端·sql·mysql
小白说大模型14 小时前
Prompt 工程的数学直觉:Embedding 空间中的 Prompt 优化的底层原理
人工智能·mysql·prompt·embedding