为什么不建议你使用自增主键

754 阅读2分钟

自增主键在不同的数据库中的存在形式稍有差异。在 MySQL 中,你可以在建表时直接通过关键字 auto_increment 来定义自增主键。

在高并发量场景下,每个事务都要去申请主键,数据库如果无法及时处理,自增主键就会成为瓶颈。那么,这时只用自增主键已经不能解决问题了,往往还要在应用系统上做些优化。所以在一个海量并发场景下,即使借助单体数据库的自增主键特性,也不能实现单调递增的主键。

分布式数据库在产生自增主键和使用自增主键两方面都有问题。生成自增主键时,要做到绝对的单调递增,其复杂度等同于 TSO 全局时钟,而且存在性能上限。使用自增主键时,会导致写入数据集中在单个节点,出现“尾部热点”问题。

尾部热点

使用单调递增的主键,也会给分布式数据库的写入带来问题。这个问题是在 Range 分片下发生的,我们通常将这个问题称为 “尾部热点”。

使用自增主键,新写入的数据往往集中在一个 Range 范围内,而 Range 又是数据调度的最小单位,只能存在于单节点,那么这时集群就退化成单机的写入性能,不能充分利用分布式读写的扩展优势了。

分布式数据库主键解决方法

由于自增主键的问题,有的分布式数据库,如 CockroachDB 更推荐使用随机主键的方式。随机主键的产生机制可以分为数据库内置和应用系统外置两种思路。内置的技术方案,有 CockraochDB 的 UUID 和 TiDB 的 RadomID。外置技术方案,有Snowflake,要注意时间回拨带来的影响。机器时钟如果出现回拨,产生的 ID 就有可能重复,这需要在算法中特殊处理一下。

结论

普通场景,自增主键还是很便捷的;高并发场景还是要谨慎使用。


此文章为6月Day17学习笔记,内容来源于极客时间《分布式数据库30讲》