当前位置: 首页 > news >正文

SQL实现UUIDv7

当我们选择数据库的主键类型时,通常会考虑自增数字或者 UUID。但是这两种类型都有优缺点,自增字段简单有序,性能良好,最大的问题是无法保证全局唯一性,分布式场景受限;UUID 具有全局唯一性,适合分布式应用,但是早期版本的 UUID 具有随机性,性能不如自增数字。

不过,随着 UUIDv7 的出现,已经解决了 UUID 没有随着时间递增的问题,它的组成如下:

在这里插入图片描述

UUIDv7 包含 128 比特(每 4 比特组成一个十六进制数字),具体包含:

  • 48 比特时间戳(精度为毫秒);
  • 4 比特UUID 版本(7);
  • 12 比特随机数字;
  • 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 没有自定义函数,可以把上面的查询定义为一个视图,实现代码复用。

其他数据库也可以按照相同的思路实现,欢迎补充。

http://www.lryc.cn/news/383959.html

相关文章:

  • 2024期权交易佣金手续费最低是多少?期权交易有哪些成本?
  • 合合信息智能文档抽取:赋能不良资产管理行业的数字化转型
  • 【别再用Excel了!】这款免费可视化工具能帮你轻松提升效率
  • python holidays获取中国节日
  • Jenkins流水线发布,一篇就解决你的所有疑惑
  • 安装zabbix时报错Could not resolve host: mirrors.huaweicloud.com;Unknown error解决办法
  • 【Linux】CentOS 7 安装配置 postfix 邮件服务器随笔
  • vue3 使用JsMind的方法,以及引入提示报错,无法找到模块“jsmind”的声明文件
  • 狗都能看懂的DBSCAN算法详解
  • 运维岗高危操作
  • 【ajax基础02】URL详解
  • MySQL 7种Join的定义图解示范结果(所有join类型)
  • 在 Oracle Linux 8.9 上安装 FFmpeg 的完整指南
  • python爬虫之实现edge无头浏览器和规避检测
  • 每天一个数据分析题(三百八十七)- 线性回归分析
  • Perl中的eval块:深入解析与应用
  • 分享AI学习笔记之Python
  • 多版本GCC安装及切换
  • Redis进阶 - 朝生暮死之Redis过期策略
  • MySQL实训--原神数据库
  • Retrieval-Augmented Generation for Large Language Models A Survey
  • 【曦灵平台】深度体验百度智能云曦灵平台之数字人3.0、声音克隆、直播等功能,AI加持就是不一样,快来一起体验
  • 如何使用GPT?初学者的指南
  • 24年了 直播带货的未来如何?
  • 【神经网络】深入理解多层神经网络(深度神经网络
  • CAS原理与JUC原子类
  • 【杂记-浅谈OSPF协议之RouterDeadInterval死区间隔】
  • 【每日刷题】Day75
  • 文件管理器加载缓慢-禁用文件类型自动发现功能
  • .[nicetomeetyou@onionmail.org].faust深入剖析勒索病毒及防范策略