数据库主键 ID 你会怎么设置

707 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

背景

近期在设计数据库时遇到一个问题,数据库 ID 设置的问题。对于该问题进行一些思考。目前基本常用设置主键 ID 方式有三种:

  • MySQL 数据库使用自增 Id 做主键
  • 使用 UUID
  • 使用雪花算法产生的 ID

设置主键

自增主键

MySQL 数据库中,设计表时直接对主键 ID 选择 AUTO_INCREMENT,这样当插入一行数据时无需指定 ID 就会自动根据前一字段的 ID值进行加1填充。

自增 ID 做主键,优点:

  • 写入数据时无需关注 Id,数据库自动填充
  • Id 类型是整型,占用的空间就比较小。
  • Id 是按顺序存放的,对于 MySQL 索引是聚簇索引,各个节点按顺序划分,索引查询时就更快速查询

但是,如果被人知道 id 是用自增,暴露出去就很容易知道你的数据量或伪造 id 值恶意爬虫数据。且如果数据量比较大时,可能结果超出整型范围。

在进行数据迁移,分表的场景下,主键是自增 Id ,但要合并数据就会让你头疼不知所措了。

UUID

uuid 是通用唯一识别码,标准是32个十六进制数组成字符串。有多个版本的 UUID。如3ca1b238-4a49-11ed-b878-0242ac120002

使用 uuid 比较合适应用在搞并发和分布式环境下的大量数据 create 和 update 操作。是全局唯一的标识,所以在数据拆分、合并存储时都很轻松解决。

相对于自增 Id ,MySQL 索引就很不利,因为 UUID 是无序的就会导致索引的性能降低。它的存储空间也大,32个字符长度的 UUID 可能就是致命伤。

雪花 ID

Twitter的雪花算法产生的不连续不重复的雪花 ID。是由机器Id+时间(毫秒级)+序列号组成。其生成的 Id 是有顺序的,所以有利于提供数据库的性能。

因雪花算法生成的ID 强依赖时间,所以在分布式场景里,如果时钟发生回拨,就可能会发生 Id 冲突的情况。

总结

总之,选择何种方式,还是要具体问题具体分析,要根据自己所使用场景上进行分析。但是自增 Id 的优势还是优于 UUID 的方式。

如果使用自增 Id,但我们可以在增加一个字符串型的唯一 code 来标识,id 不对外暴露然后根据 code 进行查询,这样就解决了被人知道的情况。在分布式的场景下,为了全局唯一还是可以推荐 twitterId 或者 UUID。