专门做地方特产的网站,虚拟会员商城网站分销,装修公司一般多少钱一平方,网站建设收费标准流程当我们选择数据库的主键类型时#xff0c;通常会考虑自增数字或者 UUID。但是这两种类型都有优缺点#xff0c;自增字段简单有序#xff0c;性能良好#xff0c;最大的问题是无法保证全局唯一性#xff0c;分布式场景受限#xff1b;UUID 具有全局唯一性#xff0c;适合…当我们选择数据库的主键类型时通常会考虑自增数字或者 UUID。但是这两种类型都有优缺点自增字段简单有序性能良好最大的问题是无法保证全局唯一性分布式场景受限UUID 具有全局唯一性适合分布式应用但是早期版本的 UUID 具有随机性性能不如自增数字。
不过随着 UUIDv7 的出现已经解决了 UUID 没有随着时间递增的问题它的组成如下 UUIDv7 包含 128 比特每 4 比特组成一个十六进制数字具体包含
48 比特时间戳精度为毫秒4 比特UUID 版本712 比特随机数字2 比特UUID 类型62 比特随机数字。 完整的 UUIDv7 介绍可以参考 RFC 9562。 UUIDv7 最大的优势是具有时间递增性和全局唯一性非常适合作为数据库的主键包括分布式数据库。
很多编程语言都提供了生成 UUIDv7 的代码库不过今天我们要介绍的是在数据库中使用 SQL 实现 UUIDv7完全不需要依赖其他组件。
首先我们来看一下 PostgreSQL 中的实现
select-- timestamplpad(to_hex(((extract(epoch from now()) * 1000)::bigint 16)), 8, 0) || - ||lpad(to_hex(((extract(epoch from now()) * 1000 (date_part(milliseconds, now())::bigint % 1000))::bigint 0xffff)), 4, 0) || - ||-- versionlpad(to_hex((0x7000 (random() * 0x0fff)::int)), 4, 0) || - ||-- variantlpad(to_hex((0x8000 (random() * 0x3fff)::int)), 4, 0) || - ||-- randomnesslpad(to_hex((floor(random() * (2^48))::bigint 16)), 12, 0) AS uuid7;uuid7 |
------------------------------------
01904fcb-0ee8-7d9c-a192-000052989c99|把上面的查询定义为一个函数就可以实现代码复用了。
接下来是 SQLite 中的实现
select-- timestampformat(%08x, ((strftime(%s) * 1000) 16)) || - ||format(%04x, ((strftime(%s) * 1000) ((strftime(%f) * 1000) % 1000)) 0xffff) || - ||-- versionformat(%04x, 0x7000 abs(random()) % 0x0fff) || - ||-- variantformat(%04x, 0x8000 abs(random()) % 0x3fff) || - ||-- randomnessformat(%012x, abs(random()) 16) as value;value |
------------------------------------
01904fd0-3dae-7460-8d4c-7d0c6b483299|SQlite 没有自定义函数可以把上面的查询定义为一个视图实现代码复用。
其他数据库也可以按照相同的思路实现欢迎补充。