Skip to content

面试速答(先看这里)

**一句话结论:**首先,获取一个自增主键是有锁竞争的,InnoDB存储引擎中有一个AUTO-INC锁,这种锁的主要目的是确保在向表中插入新记录时,每个新记录的自增列都能获得唯一的、连续的值,即使在高并发的插入操作中也能保持这一点。

60秒标准回答:

通常,我们的数据库 id 都是用自增 id 来实现的,但是这个获取自增 id 的过程会存在瓶颈吗,如果有的话,会出现在哪里呢?

首先,获取一个自增主键是有锁竞争的,InnoDB存储引擎中有一个AUTO-INC锁,这种锁的主要目的是确保在向表中插入新记录时,每个新记录的自增列都能获得唯一的、连续的值,即使在高并发的插入操作中也能保持这一点

所以, 如果并发量太大的去获取同一张表的主键的话,会存在锁竞争而影响性能

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**通常,我们的数据库 id 都是用自增 id 来实现的,但是这个获取自增 id 的过程会存在瓶颈吗,如果有的话,会出现在哪里呢?
  • **要点2:**所以, 如果并发量太大的去获取同一张表的主键的话,会存在锁竞争而影响性能。
  • **要点3:**其次,就是当我们要获取主键 id 的时候,是需要链接数据库的,而数据库的连接数是有限的,并且总数量有限,并且给每个连接他的服务器也是有数量限制的。
  • **要点4:**1、 用其他方式生成主键 :数据库存在性能瓶颈,那么我们就可以干脆不用数据库来生成id 就行了,比如说我们借助 redis来实现获取自增 id,然后直接保存到数据库中。
  • **要点5:**2、 借助缓存 :我们可以参考有一些中间件的主键 id 的获取方式,比如 tddl,他就是基于分段的思想,一次从数据库中取出一段 id,然后缓存在服务器中,当使用的时候从本地缓存中读取即可。

**记忆锚点:**redis → 借助缓存 → 用其他方式生成主键 → AUTO-INC → InnoDB → 即使在高并发

关键取舍:

  • 所以, 如果并发量太大的去获取同一张表的主键的话,会存在锁竞争而影响性能。
  • 其次,就是当我们要获取主键 id 的时候,是需要链接数据库的,而数据库的连接数是有限的,并且总数量有限,并且给每个连接他的服务器也是有数量限制的。
  • 想要优化这个过程,有几个办法: 1、 用其他方式生成主键 :数据库存在性能瓶颈,那么我们就可以干脆不用数据库来生成id 就行了,比如说我们借助 redis来实现获取自增 id,然后直接保存到数据库中。

加分表达:

  • 通常,我们的数据库 id 都是用自增 id 来实现的,但是这个获取自增 id 的过程会存在瓶颈吗,如果有的话,会出现在哪里呢?

追问准备:

  • 围绕「redis」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「借助缓存」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「用其他方式生成主键」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

通常,我们的数据库 id 都是用自增 id 来实现的,但是这个获取自增 id 的过程会存在瓶颈吗,如果有的话,会出现在哪里呢?

首先,获取一个自增主键是有锁竞争的,InnoDB存储引擎中有一个AUTO-INC锁,这种锁的主要目的是确保在向表中插入新记录时,每个新记录的自增列都能获得唯一的、连续的值,即使在高并发的插入操作中也能保持这一点。

📄 ✅高并发情况下自增主键会不会重复,为什么?

打开文档:✅高并发情况下自增主键会不会重复,为什么?

所以,如果并发量太大的去获取同一张表的主键的话,会存在锁竞争而影响性能。

其次,就是当我们要获取主键 id 的时候,是需要链接数据库的,而数据库的连接数是有限的,并且总数量有限,并且给每个连接他的服务器也是有数量限制的。所以,当并发量特别大的时候,可能会因为连接数不够而导致阻塞。

想要优化这个过程,有几个办法:

1、用其他方式生成主键:数据库存在性能瓶颈,那么我们就可以干脆不用数据库来生成id 就行了,比如说我们借助 redis来实现获取自增 id,然后直接保存到数据库中。redis 的性能要比数据库好得多。

2、借助缓存:我们可以参考有一些中间件的主键 id 的获取方式,比如 tddl,他就是基于分段的思想,一次从数据库中取出一段 id,然后缓存在服务器中,当使用的时候从本地缓存中读取即可。用完了再去数据库中申请新的一段即可。具体方案参考:

📄 ✅分表后全局ID如何生成?