HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
  • 《k8s学习心得》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
  • 《k8s学习心得》
随笔
关于作者
  • 《LearnJavaToFindAJob》

    • 导读

    • 【初级】6~12k档

    • 【中级】12k-26k档

      • JVM进阶

      • Java进阶

      • MySQL

        • Innodb和MyISAM索引的区别
        • MySQL-like是否可以使用索引
        • MySQL一些索引失效的场景和原理
        • MySQL大表索引重建
        • MySQL如何行转列?
        • MySQL死锁的场景
        • MySQL的架构和执行流程
        • MySQL的缓存
        • MySQL的自增ID用完了会怎样?
        • MySQL索引的分类、何时使用、何时不使用、何时失效?
        • MySQL联合索引在B+数的存储结构和最左匹配原则原理
        • MySQL连表优化
        • MySQL连表查询的原理
        • MySQL那种事务隔离级别性能高
        • Mysql的索引和主键的区别
        • binlog、redolog、undolog的区别和作用
        • 什么是前缀索引,什么情况才使用?
        • 可重复读是否能解决幻读?
        • 我以为我对Mysql事务很熟,直到我遇到了阿里面试官
        • 聊聊MySQL索引的分类和结构吧
        • 脏读、幻读
      • 中间件

      • 算法

      • 高阶

    • 【高级】26k+档

    • 大厂面试题

    • 求职建议

    • 面经

  • LearnJavaToFindAJob
  • 【中级】12k-26k档
  • MySQL
#Mysql #索引 #主键的区别 #索引和主键 #区别
HaC
2026-06-28
目录

Mysql的索引和主键的区别

索引是一种文件,它里面包含着对数据表里所有记录的引用指针。

# 1. 核心约束规则

1、 主键 PRIMARY KEY

  • 一张表只能有 1 个主键;
  • 字段不允许为 NULL;
  • 自动自带唯一约束,值不能重复;
  • InnoDB 中主键是聚簇索引,整行数据依附主键存储。

2、 唯一索引 UNIQUE INDEX

  • 一张表可以创建多个唯一索引;
  • 索引字段允许 NULL(多个 NULL 互不冲突,NULL != NULL);
  • 仅保证非 NULL 值唯一。

# 2. 底层索引差异(InnoDB)

1、PRIMARY KEY

  • 聚簇索引,叶子存完整行数据;
  • 不允许空值,不会存在多条 NULL。

2、UNIQUE INDEX

  • 二级普通唯一索引,叶子只存主键;
  • 支持多条 NULL 记录共存。

# 3. 额外特性

  1. 主键会自动作为表默认排序依据,查询主键极快;
  2. 主键可被外键引用;唯一索引不能直接当外键参照;
  3. 创建主键时,MySQL 自动创建索引;UNIQUE 手动创建唯一索引。

# 疑问

# Q1 表没指定主键,InnoDB 会自动生成隐藏主键吗?

会,规则分两步判断:

  1. 先找表里任意一个非空、唯一的字段,自动把它当成主键;

  2. 如果不存在满足条件的列,MySQL 自动生成隐藏列:

    row_id
    
    • 6 字节 bigint 自增;

    • 用户不可见、无法查询、无法操作;

    • 所有二级索引叶子存储这个 row_id 代替主键,导致索引变大、查询性能变差;生产环境

      强制手动设置主键,禁止依赖隐藏 row_id。

# Q2 能不能修改 / 更换主键?

万一刚开始没设置主键,后续能不能修改了? 答案是 可以,两种场景:新增主键、更换原有主键

#

-- 1. 新增主键(原本无主键)
ALTER TABLE user ADD PRIMARY KEY(id);

-- 2. 更换主键(先删旧主键,再加新的)
ALTER TABLE user DROP PRIMARY KEY, ADD PRIMARY KEY(new_id);

# Q3 修改主键会不会锁表?

分 MySQL 版本。

# 1. MySQL 5.6 / 5.7(无 Online DDL 完整支持)

执行 ALTER TABLE ... DROP/ADD PRIMARY KEY

  • 会锁表(独占写锁),期间所有 DML(增删改)阻塞;
  • 原理:InnoDB 要重建整张聚簇索引,数据全部重排复制。

# 2. MySQL 8.0(支持 Instant DDL)

  • 新增主键:依然需要重建聚簇索引,锁表;
  • 删除主键:同样重建聚簇索引,锁表;

Instant DDL 仅适用于加普通字段、删字段等轻操作,主键变更属于重排数据,不支持瞬时修改。

所以更换主键成本极高:

  1. 聚簇索引全表重建;
  2. 所有二级索引全部更新(二级索引叶子存主键,主键一变所有索引都要改);
  3. 大表会产生长时间主从延迟,线上业务尽量避免中途更换主键。

# 总结

PRIMARY KEY / UNIQUE INDEX / 普通 INDEX 完整对比表

对比维度 PRIMARY KEY 主键 UNIQUE INDEX 唯一索引 INDEX 普通索引
单表数量 仅能 1 个 允许多个 允许多个
NULL 约束 字段不允许 NULL 字段可存 NULL,多条 NULL 不冲突 字段允许任意 NULL,无唯一性限制
重复值 完全不允许重复 非 NULL 值不能重复 允许大量重复值
InnoDB 索引类型 聚簇索引,叶子存整行数据 二级唯一索引,叶子存主键 二级普通索引,叶子存主键
能否做外键参照 支持 不支持 不支持
作用 唯一标识一行、表数据存储依据 保证业务字段唯一(手机号 / 身份证) 加速等值 / 范围查询,无唯一性校验
复合字段 支持复合主键 支持复合唯一索引 支持联合普通索引
额外开销 无额外索引文件,表依赖它存储 独立索引,占用磁盘 独立索引,占用磁盘
重复插入报错 主键冲突报错 唯一键冲突报错 无报错,正常插入
#Mysql#索引#主键的区别#索引和主键#区别
上次更新: 2026-06-28 03:58:08
最近更新
01
悲观锁和乐观锁
06-28
02
MySQL-like是否可以使用索引
06-28
03
MySQL大表索引重建
06-28
更多文章>
Theme by Vdoing | Copyright © 2020-2026 HaC
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式