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          Randomness10chars            16chars48bits             80bits

组成

时间戳

  • 48位整数
  • UNIX时间(以毫秒为单位)
  • 直到公元10889年,空间都不会耗尽。

随机性

  • 80位随机数
  • 如果可能的话,采用加密技术保证随机性

排序

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

编码方式

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

0123456789ABCDEFGHJKMNPQRSTVWXYZ

二进制布局和字节顺序

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

0                   1                   2                   30 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

ULID - 一种比UUID更好的方案相关推荐

  1. NanoID 了解一下?比 UUID 更好用!

    UUID 是软件开发中最常用的通用标识符之一.然而,在过去的几年里,其他的竞品挑战了它的存在. 其中,NanoID 是 UUID 的主要竞争对手之一. 因此,在本文中,我们将展开讨论 NanoID 的 ...

  2. 比UUID更快更安全NanoID到底是怎么实现的?(荣耀典藏版)

    前言 UUID 是软件开发中最常用的通用标识符之一.然而,在过去的几年里,其他的竞品挑战了它的存在. 其中,NanoID 是 UUID 的主要竞争对手之一. 因此,在本文中,我们将展开讨论 NanoI ...

  3. 建神经网络模型,哪种优化算法更好?35000次测试告诉你丨图宾根大学出品

    萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI 想要优化自己的神经网络,却不知道哪种优化器更适合自己? 又或者,想知道深度学习中梯度下降的算法到底都有哪些? 现在,最全面的优化算法分析来了 ...

  4. dump文件_一种比Xml更敏捷的配置方式,Python Yaml 配置文件解析模块详解

    为什么选择Yaml Yaml的可读性好.扩展性好. Yaml和脚本语言的交互性好. Yaml使用实现语言的数据类型. Yaml有一个一致的信息模型. Yaml易于实现. Yaml试图用一种比Xml更敏 ...

  5. 哪种消息队列更好_如何编写更好的错误消息

    哪种消息队列更好 用户第一次遇到应用程序的文档时,并不总是带有用户手册或在线帮助. 通常,与文档的第一次相遇是一条错误消息. 技术作家应参与编写错误消息. 这是工作的重要组成部分,尽管经常被忽略. 毕 ...

  6. 那一种笔记软件更好用_制作更好的面向用户软件的7种方法

    那一种笔记软件更好用 开源一直非常擅长解决两套问题:1)基础架构和2)开发人员工具. 这是因为这些开发人员和用户基本上是同一个人-开发人员是问题的"内幕",理解得很好,并且有动机去 ...

  7. 网格自适应_网格自适应的 2 种方法——实现更高效的计算

    网格自适应的目标是修正网格以更有效地解决问题. 通常,我们希望使用尽可能少的单元来获得精确的解:并希望在不太重要的区域使用较粗糙的网格,而在感兴趣的区域使用较精细的网格.有时,我们甚至可能会考虑各向异 ...

  8. Web版和客户端哪种SQL工具更好?ChatGPT有话要说

    2023年年初公司发布了一款Web版SQL工具,短期内就赢得了众多用户的喜爱和下载.不过,也有SQL用户在评论区中提出自己的观点,认为Web版工具都不可靠,甚至看见Web版工具就劝返- - 工具Web ...

  9. ChatGPT初始,未来十年哪种后端语言更有发展前景?

    1.未来十年哪种后端语言更有发展前景? 我认为未来十年后端开发语言的前景可能会有以下几个方向: Python:Python已经成为了最流行的编程语言之一,在数据科学.机器学习.人工智能.Web开发等领 ...

最新文章

  1. 使用JQuery从客户端调用C#方法
  2. python实时获取子进程输出_Python 从subprocess运行的子进程中实时获取输出的例子...
  3. html 获取鼠标在canvas上的坐标,html5-canvas 检测鼠标在画布上的位置
  4. 这个充电宝太黑科技了,又小又不用自己带线,长见识了~
  5. C# 控制台 打印输出
  6. linux以下C 利用openssl的AES库加密,解密
  7. 求助ET服装打版软件
  8. 关于阿里矢量图标的三种使用方法
  9. 高薪岗位云计算面试题,云计算运维工程师必备
  10. Win7串口开发的的一些错误以及解决方案
  11. 一字千金的SEO达文
  12. Lazy evaluation
  13. 关于java中method.invoked 传入类型不一样的问题
  14. 论文录用后不想发了,撤稿会有什么影响吗?
  15. 如何学习Java并发编程
  16. xp系统计算机怎么连接到网络打印机,WinXP电脑如何添加网络打印机?WinXP添加网络打印机的步骤...
  17. include and extend
  18. apache配置https,并且强制使用HTTPS
  19. 对安装好的cesm测试
  20. Ipad6代支持电容笔吗?Ipad6代电容笔推荐

热门文章

  1. 美丽田园以公司实力 通过港股ipo上市一度涨近70%
  2. 15.OpenWrt-U盘和TF卡存储
  3. java portlet,(Portal 开发读书笔记)Portlet和Servlet的异同
  4. php selenium模拟登陆,python+selenium自动化实战携带cookies模拟登陆微博
  5. aliyun maven远程镜像库 mirror配置
  6. MATLAB修改字体大小,加粗,字体样式,字体颜色,线形,希腊字母,特殊符号,图片文本位置及字体设置等
  7. HLS流视频的下载方法
  8. EXCEL中SUM函数的8种用法
  9. 【高等数学】【3】微分中值定理与导数的应用
  10. TClientDataSet学习笔记