MySQL8.x 面试高频题:为什么一定要有主键?99%的人答不全



大家好呀,我是小米,今年31岁,一个喜欢折腾数据库、写Bug也写公众号的程序员。今天要和大家聊聊一个看似简单却经常出现在 MySQL8.x社招面试题 里的问题:

"为什么要尽量设定一个主键?"

听起来是不是有点小儿科?但别急,故事可精彩着呢。

我遇到的"无主键事故"

先给大家讲个亲身经历的"血泪故事"。

几年前,我接手了一个外包系统,业务方天天喊:"数据库跑得慢!查个表半天才出来!"。

我一看,居然有一张表有 几千万数据 ,而且------震惊了!竟然没有主键!

当时我心里直呼:这不是给DBA挖坑嘛!

为什么?因为没有主键的表在 MySQL 里,就像一栋楼没有门牌号,你想找人只能挨个敲门,浪费时间不说,搞不好邻居都被你吵醒。

后来我加上了自增主键,再重新梳理索引,性能立马飞升,业务方再也没催我半夜救火。

这让我彻底明白了------

有些面试题表面是送分题,背后却是生死线。

主键在 MySQL 里的地位:灵魂级存在

我们来扒一扒 MySQL 的"秘密":

InnoDB 的数据组织方式

  • InnoDB 存储引擎是 MySQL 的默认引擎,它的数据存放方式是 聚簇索引(Clustered Index)
  • 简单点说:数据行和主键绑定在一起存储,数据就是按照主键顺序排好的。

没有主键会怎样?

  • 如果你不设主键,InnoDB 会偷偷摸摸给你搞一个 6字节的隐藏主键
  • 问题是,这个隐藏主键你看不见摸不着,还不能直接利用,性能也不如你自己定义的来得清晰可控。

主键是其他索引的依赖

  • InnoDB 的二级索引(比如在 name 字段上建的索引),存的不是行数据的位置,而是 主键值
  • 查找流程是:先通过二级索引找到主键,再用主键去聚簇索引里找到整行数据。
  • 所以,主键选不好,所有索引都遭殃

为什么要尽量设定一个主键?

这里我整理了几个面试必答点,大家面试时可以直接背下来,但最好能举例子加点故事,效果更佳。

  1. 保证数据唯一性和完整性

主键是表中每行记录的身份证,天生唯一。

有了它,能避免重复插入、保证数据一致性。

就像身份证号码一样,不管你叫什么、搬去哪里,号码永远唯一。

  1. 提高查询性能
  • 有主键时,InnoDB 按照主键顺序组织数据。
  • 范围查询、排序、分页都会更快。

举个例子:

假设一张订单表 order,有主键 id,你要查 id 在 [1000, 2000] 的订单,直接走主键范围扫描,性能妥妥的。

  1. 二级索引依赖主键

刚才说过,所有二级索引都指向主键。

如果没有主键,只能依赖 InnoDB 自己生成的隐藏ID,效率差、不可控。

  1. 支持复制与恢复

MySQL 的 主从复制,binlog 里很多操作是基于主键的。

比如删除一行记录,如果没有主键,只能依靠所有字段去匹配,效率极低,还容易错删。

  1. 方便应用层开发
  • 有了主键,代码里可以直接用主键定位数据。
  • 如果没有主键,可能得用一堆字段来标识,写 SQL 又长又丑,还容易出Bug。
  1. 避免"鬼畜"的多版本控制问题

InnoDB 有 MVCC(多版本并发控制),需要依赖主键来快速定位行。

没有主键,就会导致事务管理复杂化,性能下滑。

那主键到底怎么选?

很多人以为主键随便设就行,其实里面也有学问。

1. 用自增ID做主键(最常见)

  • 简单稳定,顺序写入,页分裂少。
  • 缺点是分布式环境里不好保证全局唯一。

2. 用雪花算法/UUID

  • 分布式场景用得多。
  • 缺点:UUID 太长,顺序性差,容易导致 B+树碎片化,影响性能。
  • 改良方案:用有序的 UUID(比如时间戳 + 随机数)。

3. 业务主键

比如用订单号、学号当主键。

  • 好处:有实际意义,查起来直观。
  • 坏处:一旦业务逻辑改了,主键就容易"崩"。

我的经验总结:

  • 单机环境:自增ID。
  • 分布式环境:雪花算法ID。
  • 除非特殊需求,不要用 UUID 或业务字段做主键。

面试官可能的追问

如果你在面试时答到这里,面试官可能还会继续"刁难":

Q1:如果我没设主键,InnoDB 自动加的隐藏ID不好吗?

A:不好!因为你用不到它,所有索引查到的都是隐藏主键,再去聚簇索引找数据,绕了一大圈。而且你自己也不能控制它。

Q2:联合主键可不可以?

A:可以,但一般不推荐。因为联合主键字段多,二级索引都要存它们,导致索引体积膨胀,性能下降。

Q3:为什么自增ID比UUID更好?

A:因为自增ID是有序的,写入时不会造成页分裂。UUID 随机性太强,数据插入分布零散,会造成 B+树频繁重组,性能直线下降。

我给新人的忠告

后来我带过几个新人,我常常提醒他们:

  1. 建表时,第一步不是想字段类型,而是先想 主键选什么
  2. 绝对不要偷懒说"反正 MySQL 会给我自动加个隐藏主键"。
  3. 主键选不好,就像盖房子打地基打歪了,后面补救的代价会非常大。

总结

到这里,大家应该明白了:

主键不是可有可无的小细节,而是 MySQL 的灵魂。

  • 它让数据唯一,
  • 让索引高效,
  • 让事务轻松,
  • 让复制可靠。

面试官问"为什么要尽量设定一个主键",表面是考你知识点,实际上是在看你对 MySQL 底层原理 的理解。

如果你能结合 聚簇索引、二级索引、事务控制、复制机制 来讲清楚,就能轻松拿高分,甚至让面试官眼前一亮。

END

写到这里,我想起自己第一次答这道题的时候,还一脸懵逼地说:"因为主键能保证唯一性呀。"

面试官点了点头,表情写着:"这小伙子只会背八股。"

现在回头想想,技术成长其实就是把简单问题回答得越来越深的过程。

愿你下次面试被问到这个问题时,能像个"老司机"一样,娓娓道来。

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!

相关推荐
用户2986985301418 分钟前
.NET 文档自动化:Spire.Doc 设置奇偶页页眉/页脚的最佳实践
后端·c#·.net
随风飘的云40 分钟前
mysql的innodb引擎对可重复读做了那些优化,可以避免幻读
mysql
Lee川1 小时前
从回调地狱到同步之美:JavaScript异步编程的演进之路
javascript·面试
序安InToo1 小时前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy1231 小时前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记1 小时前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang051 小时前
VS Code 配置 Markdown 环境
后端
navms1 小时前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang051 小时前
离线数仓的优化及重构
后端
Nyarlathotep01131 小时前
gin01:初探gin的启动
后端·go