ULID - 一种比UUID更好的方案_ulid标准格式-程序员宅基地

技术标签: 架构  python  ULID  UUID  ULID vs UUID  

ULID:Universally Unique Lexicographically Sortable Identifier(通用唯一词典分类标识符)
UUID:Universally Unique Identifier(通用唯一标识符)

为什么不选择UUID

UUID 目前有 5 个版本:

版本1:在许多环境中是不切实际的,因为它需要访问唯一的,稳定的MAC地址,容易被攻击;
版本2:将版本 1 的时间戳前四位换为 POSIX 的 UID 或 GID,问题同上;
版本3:基于 MD5 哈希算法生成,生成随机分布的ID需要唯一的种子,这可能导致许多数据结构碎片化;
版本4:基于随机数或伪随机数生成,除了随机性外没有提供其他信息;
版本5:通过 SHA-1 哈希算法生成,生成随机分布的ID需要唯一的种子,这可能导致许多数据结构碎片化;

这里面常用的就是 UUID4 了,但是,即使是随机的,但是也是存在冲突的风险。
和 UUID 要么基于随机数,要么基于时间戳不同,ULID 是既基于时间戳又基于随机数,时间戳精确到毫秒,毫秒内有1.21e + 24个随机数,不存在冲突的风险,而且转换成字符串比 UUID 更加友好。

ULID特性:

ulid() # 01ARZ3NDEKTSV4RRFFQ69G5FAV
  • 与UUID的128位兼容性
  • 每毫秒1.21e + 24个唯一ULID
  • 按字典顺序(也就是字母顺序)排序!
  • 规范地编码为26个字符串,而不是UUID的36个字符
  • 使用Crockford的base32获得更好的效率和可读性(每个字符5位)
  • 不区分大小写
  • 没有特殊字符(URL安全)
  • 单调排序顺序(正确检测并处理相同的毫秒)

ULID规范

以下是在python(ulid-py)中实现的ULID的当前规范。二进制格式已实现

01AN4Z07BY      79KA1307SR9X4MV3

|----------|    |----------------|
 Timestamp          Randomness
  10chars            16chars
   48bits             80bits

组成

时间戳
  • 48位整数
  • UNIX时间(以毫秒为单位)
  • 直到公元10889年,空间都不会耗尽。
随机性
  • 80位随机数
  • 如果可能的话,采用加密技术保证随机性
排序

最左边的字符必须排在最前面,最右边的字符必须排在最后(词汇顺序)。必须使用默认的ASCII字符集。在同一毫秒内,不能保证排序顺序

编码方式

如图所示,使用了Crockford的Base32。该字母表不包括字母I,L,O和U,以避免混淆和滥用。

0123456789ABCDEFGHJKMNPQRSTVWXYZ
二进制布局和字节顺序

组件被编码为16个八位位组。每个组件都以最高有效字节在前(网络字节顺序)进行编码。

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      32_bit_uint_time_high                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     16_bit_uint_time_low      |       16_bit_uint_random      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       32_bit_uint_random                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       32_bit_uint_random                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

应用场景

  • 替换数据库自增id,无需DB参与主键生成
  • 分布式环境下,替换UUID,全局唯一且毫秒精度有序
  • 比如要按日期对数据库进行分区分表,可以使用ULID中嵌入的时间戳来选择正确的分区分表
  • 如果毫秒精度是可以接受的(毫秒内无序),可以按照ULID排序,而不是单独的created_at字段

用法(python)

安装

pip install ulid-py

创建一个全新的ULID。

时间戳记值(48位)来自 time.time(),精度为毫秒。

随机值(80位)来自 os.urandom()

>>> import ulid
>>> ulid.new()
<ULID('01BJQE4QTHMFP0S5J153XCFSP9')>

根据现有的128位值(例如UUID)创建新的ULID 。
支持ULID值类型有 int,bytes,str,和UUID。

>>> import ulid, uuid
>>> value = uuid.uuid4()
>>> value
UUID('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')
>>> ulid.from_uuid(value)
<ULID('09GF8A5ZRN9P1RYDVXV52VBAHS')>

从现有时间戳值(例如datetime对象)创建新的ULID 。
支持时间戳值类型有int,float,str,bytes,bytearray,memoryview,datetime,Timestamp,和ULID

>>> import datetime, ulid
>>> ulid.from_timestamp(datetime.datetime(1999, 1, 1))
<ULID('00TM9HX0008S220A3PWSFVNFEH')>

根据现有的随机数创建一个新的ULID。

支持随机值类型有int,float,str,bytes,bytearray,memoryview,Randomness,和ULID。

>>> import os, ulid
>>> randomness = os.urandom(10)
>>> ulid.from_randomness(randomness)
>>> <ULID('01BJQHX2XEDK0VN0GMYWT9JN8S')>

一旦有了ULID对象,就有多种与之交互的方法。

timestamp()方法将为您提供ULID的前48位的时间戳快照,而randomness()方法将为您提供后80位的随机数快照。

>>> import ulid
>>> u = ulid.new()
>>> u
<ULID('01BJQM7SC7D5VVTG3J68ABFQ3N')>
>>> u.timestamp()
<Timestamp('01BJQM7SC7')>
>>> u.randomness()
<Randomness('D5VVTG3J68ABFQ3N')>

github: https://github.com/ahawker/ulid

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pushiqiang/article/details/117365290

智能推荐

[Win7/Win10]如何有效地关闭自动更新(Windows Update)_笔记本wim7总自动更新怎么关闭-程序员宅基地

文章浏览阅读1.1k次。 尝试过很多办法去关闭自动更新,但是过几天总是会卷土重来。虽然自动更新更加安全,但对于我们日常用户来说,自动更新总是带来很多麻烦。那么,应当如何有效地关闭自动更新呢? 1,按下win+r键打开“运行”窗口,输入“gpedit.msc”打开组策略。如图:2,依次点击“计算机配置-管理模板-Windows组件”,如图:3,在右边找到“Windows Update”(win..._笔记本wim7总自动更新怎么关闭

IIS 之 在IIS7、IIS7.5中应用程序池最优配置方案_设置iis进程模型-程序员宅基地

文章浏览阅读1k次。找到Web站点对应的应用程序池,“应用程序池” → 找到对应的“应用程序池” → 右键“高级设置...”  一、一般优化方案  1、基本设置  [1] 队列长度: 默认值1000,将原来的队列长度改为 65535。  [2] 启动32位应用程序:默认值False,改为True, 否则安装一些32的组建或32位的php都会出错。  [3] 托管管道模式_设置iis进程模型

three.js建立一个可交互的机房机柜_three.js 机房 源码-程序员宅基地

文章浏览阅读5.9k次,点赞9次,收藏44次。<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>一个可以开门的机柜</title> <style> *{ margin:0; pa..._three.js 机房 源码

QTextEdit个人使用心得_qtextedit qpixmap-程序员宅基地

文章浏览阅读2.3k次,点赞7次,收藏11次。本篇文章讲述的是对Qt QTextEdit控件在使用中获得的一些心得和遇到的一些问题以及解决办法。采用了一些前辈的方法(在此不再一一列出地址,时间久远具体链接找不到了,如有需要请搜索其关键字,抱歉了)并加以改进的,算是在此记录自己成长的过程,分享出来希望能帮助到有需要的人。_qtextedit qpixmap

shell中的比较运算符 -eq -ne -gt -lt -ge -le 及 == != 与 逻辑运算符$$ || !_shell -ne-程序员宅基地

文章浏览阅读4.5w次,点赞14次,收藏64次。shell中的比较运算符:-eq //等于-ne //不等于-gt //大于 (greater)-lt //小于(less)-ge //大于等于-le //小于等于命令的逻辑关系:在 linux 中命令执行状态:0 为真,其他为假 。$? 是显示最后命令的退出状态,0 表示没有错误,其..._shell -ne

【C++】关于lower_bound和upper_bound的使用-程序员宅基地

文章浏览阅读263次。lower_bound与upper_bound从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。upper_bound(begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

随便推点

C语言第五课-输出双精度(double)数_c语言中整型变量计算输出双精度-程序员宅基地

文章浏览阅读803次,点赞8次,收藏12次。/ 定义双精度变量。使用 printf() 与 %e 输出双精度数。C 语言实例 - 输出双精度(double)数。printf("d 的值为 %le", d);// 声明双精度变量。d 的值为 1.200123e+01。_c语言中整型变量计算输出双精度

12c 2cpu oracle se_Oracle GoldenGate价格(11G/12C中文企业版2CPU)-程序员宅基地

文章浏览阅读838次。OracleGoldenGate,简称OGG,是一种基于日志的结构化数据复制备份软件,它通过解析源数据库在线日志或归档日志获得数据的增量变化,再将这些变化应用到目标数据库,从而实现源数据库与目标数据库同步。OracleGoldenGate可以在异构的IT基础结构(包括几乎所有常用操作系统平台和数据库平台)之间实现大量数据亚秒一级的实时复制,从而在可以在应急系统、在线报表、实时数据仓库供应、交易..._cpu 12c*2 6626

mysql发送数据网页显示,通过JSP网页链接MySQL数据库,读取数据库显示在JSP网页...-程序员宅基地

文章浏览阅读579次。通过JSP网页链接MySQL数据库,读取数据库显示在JSP网页通过JSP网页链接MySQL数据库,读取数据库显示在JSP网页通过JSP网页连接MySQL数据库,从MySQL数据库中读出一张表并显示在JSP网页中一. 安装所需软件安装java和tomcat,建立JSP网页最基础的软件;安装MySQL数据库(下载地址:https://www.mysql.com;安装Navicat Premium来查看..._mysql数据如何挂到网页

17 -> 详解 openWRT 的 gpio 配置关系说明_openwrt gpio dts-程序员宅基地

文章浏览阅读3.2k次。OpenWRT 系统的 gpio 可用配置为键盘输入、led输出、控制输出等,以 mt7621 为例,相互关系说明如下:第一步 查看设备树配置文件/OpenWrt/mtk7621-19.07$ ls target/linux/ramips/dts/ | grep 7621AP-MT7621A-V60.dtsMT7621.dtsmt7621.dtsi #(1) mt7621 芯片资源的基本配置文件U7621-06-256M-16M.dts # (3)_openwrt gpio dts

mate20pro怎样装鸿蒙系统,华为放大招!华为Mate20系列也能拍月亮,以后还能升级鸿蒙...-程序员宅基地

文章浏览阅读3.7k次。上半年国内手机市场的新机数量明显减少,但也出现了一些可喜的变化,比如一加7 Pro使用2K分辨率90Hz刷新的屏幕,比如低亮度无频闪的DC调光。相比前一项,DC调光更值得关注,因为这是在网友的驱动下出现的改变。支持DC调光可以让屏幕在低亮度下无频闪,减少对眼睛的伤害。魔法师蛋小丁提出来之后,OPPO首先响应,随后蔓延至整个手机行业。到现在为止,上半年发布的旗舰手机大都支持DC调光,即使硬件不支持,..._华为mate20pro更新鸿蒙系统后有月亮模式吗

JWT 和 JJWT 的区别?别再傻傻分不清了。。_java-jwt 与jjwt有什么区别-程序员宅基地

文章浏览阅读1k次。jwt是什么?JWTs是JSON对象的编码表示。JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值。JWT有助于在clear(例如在URL中)发送这样的信息,可以被信任为不可读(即加密的)、不可修改的(即签名)和URL - safe(即Base64编码的)。jwt的组成Header: 标题包含了令牌的元数据,并且在最小包含签名和/或加密算法的类型Claims: Claims包含您想要签署的任何信息JSON Web Signature (JWS): 在header中指定的_java-jwt 与jjwt有什么区别