本文提供一种PostgreSQL的UID生成策略,参考自Instagram公开的一种方案,除了可以确定产生的ID是唯一值以外,还有以下几种优点:
- 生成的ID按照时间排序(但排序结果跟插入顺序不一定一致)
- ID长度为64bit,不会过大
- 支持数据库集群(通过定义分片ID保证不同分片之间生成的ID不会重复)
可以为数据库字段赋予默认值为下面的next_id()
函数,即可为每条记录产生唯一的值:
1 | -- CREATE SEQUENCE |
第一部分SQL是创建一个循环的SEQUENCE,第二部分是用来重置SEQUENCE的值,第三部分是创建供调用的函数。其中函数部分,now_millis
用来获取当前时间的毫秒值;our_epoch
定义了一个指代业务开始的时间毫秒值,可自定义,为了降低毫秒数的初始值;shard_id
是为分布式数据库定义的一个分片ID,每个数据库(分片)的ID不能一样,为了确保多个数据库(分片)之间不会生成相同的ID;seq_id
是通过SEQUENCE生成的一个自增长的序列。具体数据存储如下:
- 41bits存储毫秒时间
- 13bits存储逻辑分片的ID
- 10bits存储序列对1024求模的结果
可以让每个分片在每毫秒里能产生1024个唯一的ID,对RDBMS的性能来说是足够的。当然日后如果有并发量达到每秒10万以上的性能,也可以调整后面求模的数值并调整存储位的分布。