跳到内容

你使用什么作为数据库的 ID?

发布于:2023年12月18日,最后更新:2024年1月9日

1. 引言

软件 ID 是计算机系统中的重要概念,它用于标识不同的数据实体和交互过程。ID 生成方案是指用于生成唯一标识符(ID)的算法或方法。这些标识符通常用于唯一标识数据库中的记录、消息队列中的消息、分布式系统中的节点等。

一个好的 ID 生成方案应该能够生成唯一的 ID,并且应该是高效的,在处理大量数据时不会影响性能。

理想的唯一 ID 有以下特性:

2. 常用的 ID 生成方案

★ 介绍一款能够查看各种 ID 介绍,并且能生成 ID 的工具:ID Master

2.1. 数据库自增 ID

数据库自增 ID 是一种常见的唯一标识符生成方案,依赖于所使用数据库的本身机制,不赘述了。

2.2. UUID

UUID 常用的是版本 4。有很多讨论是关于数据库自增 ID 好还是 UUID 好。

这样的讨论很多,我个人觉得虽然有各种缺点,但是 UUID 是一个比数据库自增 ID 更好的选择。

2.3. Twitter 雪花(Snowflake)算法

Snowflake 是由 Twitter 开发的一种分布式 ID 生成算法,可以保证 ID 的唯一性和足够的可排序性。Snowflake 的 ID 格式为 64 位整数,其中第 1 位为符号位,接下来的 41 位为时间戳,10 位为节点 ID,12 位为序列号。

它具有以下特点:

  1. 全局唯一性:在不同的机器上生成 Snowflake ID,几乎不可能出现重复的情况。
  2. 时间有序性:Snowflake ID 中包含了时间戳信息,因此可以根据 Snowflake ID 的大小来推断生成时间的先后顺序。
  3. 可读性:Snowflake ID 采用了固定的 64 位二进制格式,使得其可以被人类较易读懂。
  4. 分布式生成:Snowflake ID 可以支持分布式系统,每个节点都可以生成唯一的标识符,从而避免了单点故障。
  5. 高性能:Snowflake ID 的生成过程非常快速,因为它是纯内存操作。同时,Snowflake ID 的长度为 64 位,比许多其他唯一标识符更短,而且更加紧凑。

3. 一些较新的方案

这个才是这篇文章的重点。

较新的方案一般有如下特点:

3.1. UUID v678

IETF 在起草新的 UUID 格式,也是顺应的应用的趋势。

其中看到两个趋势:

  1. 性能:v6 和 v7 都有考虑可排序性,解决 UUID 应用时最常遇到的数据库性能问题
  2. 可自定义性:应用需求前变万化,一个标准解决不了全部问题,市面上有了各种各样的 ID 生成方案,于是有了 v8

3.2. ULID

ULID(Universally Unique Lexicographically Sortable Identifier)是一种基于时间戳的唯一标识符,具有以下特点:

  1. 全局唯一性:在不同的机器上生成 ULID,几乎不可能出现重复的情况。
  2. 时间有序性:ULID 中包含了时间戳信息,因此可以根据 ULID 的大小来推断生成时间的先后顺序。
  3. 可读性:ULID 使用了基于 Crockford’s Base32 编码的字符集,使得其可以被人类较易读懂。
  4. 长度适中:ULID 的长度为 26 个字符,比许多其他唯一标识符更短,而且更加紧凑。

高位 48 位时间+低位 80 位随机数,使用 base32 编码为 26 个字符的字符串。

3.3. Nano ID

Nano ID 是一种轻量级、高性能的 ID 生成器,采用了类似 Twitter 的 Snowflake 算法。Nano ID 的长度为 21 个字符,其中 15 个字符用于表示时间戳,6 个字符用于生成随机数,可以保证 ID 的唯一性和足够的随机性。Nano ID 适用于高并发环境下的 ID 生成,例如 URL 缩短服务等。但是,Nano ID 不适用于需要支持排序或时间相关操作的场景。

3.4. KSUID

来自 CDP 厂商 Segment。

高位 20 位时间+低位 128 位随机数,使用 base62 编码为 27 个字符的字符串。

3.5. TSID

时间有序的 64 位整数,使用 base32 编码为 13 个字符的字符串。

3.6. Cuid2

通过多轮迭代计算,生成指定长度的Base36编码字符串,主打一个安全,但是计算速度慢。时间无序。

4. 如何选择合适的 ID 生成方案

方案数字位数字符串长度时间有序
自增长 ID641-20
UUID12836取决于版本
Snowflake641-19
ULID12826
Nano ID6421
KSUID16027
TSID6413
Cuid2可变可变

选择哪种 ID 生成方案取决于应用程序的需求和预期的负载。

目前我选择的是 ULID。为什么不选 KSUID?虽然随机数很多(避免碰撞),但是它的时间精度不够。

5. 参考资料

欢迎关注同名微信公众号,文章自动推送:

nomadic-blood