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 更加友好,
推薦一個開源免費的 Spring Boot 最全教程:
https://github.com/javastacks/spring-boot-best-practice
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 = https://www.cnblogs.com/javastack/archive/2022/11/29/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
著作權宣告:本文為CSDN博主「pushiqiang」的原創文章,遵循CC 4.0 BY-SA著作權協議,轉載請附上原文出處鏈接及本宣告,原文鏈接:https://blog.csdn.net/pushiqiang/article/details/117365290
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2022最新版)
2.勁爆!Java 協程要來了,,,
3.Spring Boot 2.x 教程,太全了!
4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/538691.html
標籤:其他
上一篇:SpringCloud Alibaba(四) - Nacos 配置中心
下一篇:<九>理解虛繼承和虛基類
