ID生成工具整理

ID生成工具整理

UUID、ULID、SnowflakeId、Ksuid、NanoId等编号生成工具功能比较

前言

在设计软件时,数据主键的设计是一个很重要的事情,一条数据的编号关系到数据的唯一性判断与检索定位。

关系数据库理论里面提到了键(key,码)与主键(primary

key,主码),在例子里面一般都使用学号、产品编号等来演示。但并未过多提到这种唯一编号的生成方式。实践中,通常会用随机字符串、自增序列等方式作为唯一编号。

编号不仅会用于软件中的数据存储,也会用在数据交换、人机信息传递等场合。

本文整理几种常见编号生成算法(表格 1),并按照时间顺序介绍这些工具。

汇总表

表格 1 编号生成工具简表

名称(字母顺序)

长度(bits)

保留位(bits)

字符串长度(表示法)

优化时间排序

例子

Ksuid

160

0

27(base62)

2dJf4bxMcdyAo5UhH3EFJKOt380

MongoDB ObjectId

96

0

26(hex)

ObjectId("507f1f77bcf86cd799439011")

Nano ID

128

2

21(base64)

随机

ofouG6h5HRadNRgW_atUB

SnowflakeId

64

1

19(10进制)

9223372036854775807

ULID

128

0

26(base32)

01HR9YEEJ9JP6TT2SSF72QDTF6

UUIDv1

128

6

36(hex)

随机

23ab203a-b193-1016-b803-9600026de545

UUIDv4

128

6

36(hex)

随机

07e964b7-3fb5-46fe-b07f-61ec69dbe9ae

UUIDv6

128

6

36(hex)

016b1932-3daa-6b61-b804-45014d54d2ff

UUIDv7

128

6

36(hex)

018e13e7-0e77-7ba6-a0e8-52b6bdb47eb7

UUIDv8

128

6

36(hex)

自定义

——

UUID

Universally Unique Identifier(UUID),全局唯一标识,由RFC4122规范所定义。Windows系统中习惯叫做Globally Unique Identifier (GUID)。该规范在ISO/IEC及ITU-T同样有采用。

UUID可追溯到1980年代,当时Apollo 公司在设计网络计算系统(Network Computing System,NCS)时为了唯一地识别系统中的每个节点,于是提出UUID方案。后来,开放软件基金会(Open Software Foundation,OSF)设计的分布式计算环境(Distributed Computing Environment,DCE)以及微软的Windows平台中均有采用该方案。到1998年时,互联网工作组(Internet Engineering Task Force ,IETF)吸纳其成为标准,编号RFC4122。

UUID实质为一个128bits(16bytes)的二进制数,在其中保留6位用于协议识别。转换成10进制会有39位之长。

为了方便识别和阅读,同时设计一种标准的字符串表示法(16进制):xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(8-4-4-4-12分隔,每个x实际为0-F的16进制字符)。Windows中还有用大括号括起来的形式{......}。有人也习惯把分隔符去掉来减少长度,但只有第一种是标准形式。UUID最小是(也叫Nil UUID):00000000-0000-0000-0000-000000000000,最大是:FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF。

2003年时,注册申请到urn标识,可以写作:urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6。

UUID发展出多个版本来适应不同需求,版本1-5发布于2005年之前。主要差异在于生成思路上,详细说明可以参考规范原文。

UUID v1 与 UUIDv4

UUID第三组前4个位是版本代号,第四组前2位是变体代号。

V1版( Gregorian Time-based UUID)使用机器的公历日期、时钟、随机数与MAC地址组合而成。例如“b375c417-b1ac-1016-b9af-9600026de545”。

V4版(Random)则全部使用随机数来组合,例如“9960b102-0639-4eef-8c2f-99074a6ccaab”。“java.util.UUID#randomUUID”采用的也是这一版设计。

UUIDv3 与 UUIDv5

V3(MD5 Name-based)与V5(SHA-1 Name-based)用于将指定名字空间(如DNS、URL、OID、X500)的名字转换成UUID表示法。不同的是v3采用MD5摘要算法,v5采用SHA-1。

举例:UUIDv3(URL,http://www.baidu.com)=2f67490d-55a4-395e-b540-457195f7aa95

V2(DCE Security)专用于DCE Security ,并未在RFC中讨论。

MongoDB ObjectId

2009年MongoDB数据库发布,里面设计有名为ObjectId的数据类型,也是一个主键生成算法。

ObjectId长度为96bits,由32位的Unix Epoch 时间戳、40位随机数(进程标识),24位顺序递增码(随机开始)组成。

可以表示成24位长的16进制数,例如“ObjectId("507f1f77bcf86cd799439011")”

SnowflakeId

习惯叫雪花算法。2010 年Twitter 开源了他们团队在用的这种全局唯一ID生成工具。其特点是可用于分布式系统中各节点生成ID,可按照生成时间排序,不连续递增。

SnowflakeId是一个64 bits二进制数。为了避免负数,最高位永远置0,实际使用63 bits。由系统时间戳、机器识别码、顺序号组成。

在SnowflakeId基础上,发展出多种变体,如百度的、美团的、微信的等。

Ksuid

K-Sortable Unique Identifier(Ksuid)。Twilio Inc在比较了UUID、Snowflake ID的特点后,在2017年提出一种新的ID生成算法。特点是可按照生成时间排序,无协调机制,碰撞概率低。

设计为160 bits长,由32位时间戳、128位随机数组合而成,比UUID更长。使用Base62编码方式表示为27位长的字符串。例如“2dtpkbpDpweYidSNJZabF9xo5Cz”。

NanoId

NanoId ID,2017年,作者是Evil Martians。使用随机数来生成ID,并将数字值编码为字符串(base64),在128bit随机数的情况下,可以编码为21个字符。

字符串长度、字典表均可自行调整,方便在简便情况下生成更短的ID。与其相似的还有squids(曾经叫hashids)

ULID

Universally Unique Lexicographically Sortable Identifier。为了克服UUID(v1-v5)排序不便的问题,民间组织在2017年新提出的一种ID生成算法。

长度128 bits,由前48位时间戳、后80位随机数组成。可按时间排序,利于数据库索引。使用base32编码为长度为26的字符串。例如“01ARZ3NDEKTSV4RRFFQ69G5FAV”。

UUIDv6-v8

因被吐槽不能按时间排序,不利于数据库索引优化,而新设计的版本。从2021年开始设计,增加3个版本,目前提案已经定稿,等待审定公布。

V6(Reordered Gregorian Time-based) 与 v1生成思路接近,但字节序做了调整以支持时间排序,MAC地址则换成了随机数。

V7(Unix Time-based)进一步采用了Unix Epoch timestamp做时间戳,更接近主流的选择。

V8(Custom)则是一个完全自由的版本。除了固定的6位版本识别外,不定义生成方法,用户可以自己设计决定。这意味着你有122 bits可用,你可以将许多短于这个长度的ID编码成UUID。

未来应该会主推UUIDv7了。

小结

编号本质上是有状态服务,因为其要具备唯一性识别的作用。例如钞票的编号,发票的号码,身份证号码,订单号等。

编号生成一般依赖机器时钟、机器识别码、随机数或者中心化的编号池分配等设计。

在不同需求下编号生成的算法有所不同,自增序列、UUID是常见的方案。

参考资料

[1] https://datatracker.ietf.org/doc/draft-ietf-uuidrev-rfc4122bis/14/ —— rfc4122新草案

[2] https://segment.com/blog/a-brief-history-of-the-uuid/ —— UUID历史

[3] https://idtools.co/uuid/v1 —— 在线生成UUID的工具,可用于演示

相关文章

特斯拉汽车有哪些车型?
365账号限制登录不了

特斯拉汽车有哪些车型?

📅 07-09 👁️ 5673
卡塔尔世界杯日本队赛程,十二强赛赛程时间,详细赛程表及比赛场次
月光女神
365账号限制登录不了

月光女神

📅 08-23 👁️ 6718