閒談軟體設計:UUID & ULID

更新 發佈閱讀 7 分鐘
圖片來源:ChatGPT 生成

圖片來源:ChatGPT 生成

本想說,《閒談軟體設計 2014 ~ 2024》裡已經談了三回的 UUID,應該不會再有機會談到 UUID,作為我常用的資料庫主鍵,這麼多年過去了,難道沒有任何新意嗎?趁著系統要加入一個新模組,我稍微研究了一下,沒想到還真的有,UUID 家族新增了 v6 和 v7,還有一個同樣是 128-bits 長度的 ULID,今天就聊聊這兩個新玩意吧。

UUID v6 & v7

第一篇聊 UUID,是寫在 2017 年,當時的標準規範是 RFC 4122,此標準中 UUID 有五個版本,只有第一個版本算是 Time-based,但因為時間戳記的位元分布有點怪,導致無法滿足依時間排序,每隔一段時間,就會因為低位元重置導致排序亂掉。

所以在第一篇討論 UUID 時,就有提過,透過調整時間戳記的位元分布,是可以產生能按時間排序的 UUID。這個概念正好就是 UUID v6 和 v7 的核心概念,UUID v6 和 v7 是在 2020 的 RFC 9562 中提出,在 2.1 節中,條列了幾項為什麼要提出 RFC 9562 來擴充 RFC 4122 (僅列與本文相關的幾項):

  • 既有的 UUID 無法按時間排序 (v3、v4 和 v5)
  • 每 100 奈秒的計數作為時間戳記不常見也不容易用 IEEE 754 呈現 (v1)
  • 需要解析才能按時間排序 (v1)
  • 未明確區分「產生 UUID」與「儲存 UUID」的不同需求

所以 UUID v6 和 v7 到底和 v1 哪裡不一樣?直接看 128-bits 的內容配置是最清楚的,UUID v1 把時間戳記的最低 32 bits 擺在最高位 (這是無法按時間排序的主要原因)。

UUID v1 Layout (擷取自 RFC 9562)

UUID v1 Layout (擷取自 RFC 9562)

因此,UUID v6 提供一個幾乎與 v1 幾乎一樣,唯一差別是把時間戳記的最高 32 bits 擺在最高位,也就不會有每隔一陣子順序就亂掉的問題。

UUID v6 Layout (擷取自 RFC 9562)

UUID v6 Layout (擷取自 RFC 9562)

而 UUID v7 則是只使用 48-bits 的時間戳記,而且是直接使用毫秒,不再是每 100 奈秒的計數,更重要的是,時間戳記不再拆成三段,讓解讀上更容易,除了時間戳記、版本和變體需要的位元外,其他都是亂數,不再使用任何可識別主機位置的資訊,提高了安全性。

UUID v7 Layout (擷取自 RFC 9562)

UUID v7 Layout (擷取自 RFC 9562)

從上述的配置可以看到,UUID v6 和 v7 就是希望讓 UUID 能夠按時間排序。

除此之外,UUID 產生出來,很大的機會是要儲存的,目前很多資料庫中,UUID 已經被當成主鍵的常用選項之一,而 UUID v6 和 v7 的設計相較於完全隨機的 UUID v4 來說,資料庫的索引 (index) 是有機會最佳化的,讓時間戳記相近的 UUID 可以存在 B-Tree 同一個節點中,在磁碟讀取時只需要一次操作就可以取得相近的 UUID,能增加查詢的效率。

ULID

既然新版的 UUID 這麼好,就通通改成用新版的?這倒是不一定,有幾個情況要觀察一下,首先是程式語言的支持,Java 25 還沒有內建對 v6 及 v7 的支援,必須用第三方套件;另外,資料庫是否能正確處理新版的 UUID?最後就是 UUID 真的很長,十六進制的表示法,加上連字號,36 個字母,在很多場景下真的很難使用,也因此在第二篇聊 UUID 的文章中,透過 Base 32 編碼讓 UUID 變短一點。

RFC 9562 的 2.1 節中提到,在制訂新 UUID 標準中,參考 16 種既有技術,其中包含了 ULID。ULID 的全名是 Universally Unique Lexicographically Sortable Identifier,從名稱上就可以看得出意圖:可以按字典排序,或是換個說法,可以用字串排序。

ULID Layout (擷取自官網)

ULID Layout (擷取自官網)

從 ULID 的配置可以看的出來,長度依然是 1288-bits,最高的 48 bits 是時間戳記,剩餘的 80 bits 都是亂數,但採用 Base 32 編碼,只能說英雄所見略同 (自己說的 XD),因此產生出來的 ID 長度是 26 個字元,雖然不是最短的,但沒有特殊符號,且不分大小寫 (Base 64 會有特殊符號且分大小寫),作為網址的一部分是安全的。

魔術數字 48

不知道有沒有人注意到,UUID v6 與 v7,以及 ULID 在時間戳記的長度都只取 48 bits 呢?答案其實很簡單,以寫文章的當下 2025-12-13 12:50:30 (台北時間),時間戳記是 1,765,601,430,000 ms,很大的一個數對吧,那以二進制表示會是 0001 1001 1011 0001 0110 0000 1011 1100 1001 1111 0000,長度也才來到 44 bits,如果取一個長整數 (long) 的長度,也就是 64 bits,那最高的 20 bits 全是 0,產生出來的 UUID 會是五個 0 開頭,不要說這五個 0 什麼時候會變成 1,光是剛剛的時間戳記,最高的四個位元 0001 變成 0010是 2060 年的事了,變成 0011 是 2095 年,變成 0100 是 2130 年,等到 1111 用完需要進位,是 2513 年,到時候,我想 UUID 應該已經退出科技的舞台了。

小節

小節一下,ID 的產生其實是一門有趣的學問,會根據使用的情境選擇合適的 ID 產生方式,資料庫的 auto increment 不是不能用,實際上,它還是很好用的,只是產生的效率和使用的情境都會被資料庫綁住,這也是我越來越少用的原因。

回到文章的開頭,新模組選擇 UUID 還是 ULID 呢?都不是 (笑),最後,借鏡了 Slack 的模式,使用了單純的 {timestamp}.{seq}{random},seq 確保在同個程序中,相同時間取 ID 時遞增,再加上一個 random,讓衝突的機率降低,其實就算碰撞了,資料庫也會阻擋寫入,重新再產生一個 ID。

會整理這篇,主要是提醒自己,技術是會隨著時間不斷進化,定期檢視一些自己以為很瞭解的技術,是有必要的。


留言
avatar-img
留言分享你的想法!
avatar-img
Spirit的沙龍
56會員
110內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
Spirit的沙龍的其他內容
2025/11/22
分享自身團隊在 Cloudflare 當機時,如何透過事先規劃的備援機制,在極短時間內將服務切換至 GCP Cloud DNS 並恢復正常運作的經驗。文章深入探討備援設計的複雜性,涵蓋成本、同步、複雜度及演練等面向,並總結事後檢討,強調建置外部監控系統和自動化 SSL 憑證更新的重要性。
Thumbnail
2025/11/22
分享自身團隊在 Cloudflare 當機時,如何透過事先規劃的備援機制,在極短時間內將服務切換至 GCP Cloud DNS 並恢復正常運作的經驗。文章深入探討備援設計的複雜性,涵蓋成本、同步、複雜度及演練等面向,並總結事後檢討,強調建置外部監控系統和自動化 SSL 憑證更新的重要性。
Thumbnail
2025/06/29
本文探討後端 API 安全驗證機制,說明如何基於請求憑證進行身家調查,確保只有授權使用者才能存取資源。文中詳細闡述了資料採信原則、角色來源、組織層級的設計考量,並介紹簡單的實作範例,以確保系統安全。
Thumbnail
2025/06/29
本文探討後端 API 安全驗證機制,說明如何基於請求憑證進行身家調查,確保只有授權使用者才能存取資源。文中詳細闡述了資料採信原則、角色來源、組織層級的設計考量,並介紹簡單的實作範例,以確保系統安全。
Thumbnail
2025/06/22
本文探討如何使用函數式風格聲明 Javalin API endpoint 的安全性需求,並透過組合函數,例如 any 和 all,以及自定義函數,例如 anyManager 和 anyOwner,來簡化複雜的權限檢查。此方法避免了使用註解的繁瑣,並提高了程式碼的可讀性和可維護性。
Thumbnail
2025/06/22
本文探討如何使用函數式風格聲明 Javalin API endpoint 的安全性需求,並透過組合函數,例如 any 和 all,以及自定義函數,例如 anyManager 和 anyOwner,來簡化複雜的權限檢查。此方法避免了使用註解的繁瑣,並提高了程式碼的可讀性和可維護性。
Thumbnail
看更多
你可能也想看
Thumbnail
作者分享自己曾在蝦皮購買的好物,與介紹蝦皮雙12購物節的優惠活動,以及自己打算入手的商品,也詳細說明如何透過「蝦皮分潤計畫」創造額外的被動收入,鼓勵讀者一同參與。
Thumbnail
作者分享自己曾在蝦皮購買的好物,與介紹蝦皮雙12購物節的優惠活動,以及自己打算入手的商品,也詳細說明如何透過「蝦皮分潤計畫」創造額外的被動收入,鼓勵讀者一同參與。
Thumbnail
交換禮物總是讓人又愛又怕?Ruby整理蝦皮500元內必買清單,從養生茶包、心靈牌卡到可愛環保杯、公益零錢包,送禮自用兩相宜。同時分享「蝦皮分潤計畫」教學,購買好物的同時還能賺零用錢,雙12購物攻略一次看!
Thumbnail
交換禮物總是讓人又愛又怕?Ruby整理蝦皮500元內必買清單,從養生茶包、心靈牌卡到可愛環保杯、公益零錢包,送禮自用兩相宜。同時分享「蝦皮分潤計畫」教學,購買好物的同時還能賺零用錢,雙12購物攻略一次看!
Thumbnail
冬天到了,又到了我最愛窩在家網購的季節!從原本對網拍沒興趣,到現在成為蝦皮的忠實用戶,這個轉變連我自己都覺得有趣。這次趁著蝦皮雙12活動,想跟大家分享我最近入手的冬季養生好物——艾灸罐,還有其他實用的生活小物。文末也會介紹蝦皮分潤計畫,讓常網購的你,也能把購物經驗變成額外收入!
Thumbnail
冬天到了,又到了我最愛窩在家網購的季節!從原本對網拍沒興趣,到現在成為蝦皮的忠實用戶,這個轉變連我自己都覺得有趣。這次趁著蝦皮雙12活動,想跟大家分享我最近入手的冬季養生好物——艾灸罐,還有其他實用的生活小物。文末也會介紹蝦皮分潤計畫,讓常網購的你,也能把購物經驗變成額外收入!
Thumbnail
以前只有用過 iMove 剪過自己的結婚成長影片,就是用一些照片幻燈片搭配感動的音樂,雖然技術力薄弱,但在婚禮現場播放時,可能只有我自己看得懂那段影片的故事,我居然哭到淚流不止啊!婚攝大哥也很敬業,就把那個瞬間捕捉下來了。 後來也是因為工作上的需求,有嘗試過有各種行動剪輯軟體來完成一些小短片,所以還
Thumbnail
以前只有用過 iMove 剪過自己的結婚成長影片,就是用一些照片幻燈片搭配感動的音樂,雖然技術力薄弱,但在婚禮現場播放時,可能只有我自己看得懂那段影片的故事,我居然哭到淚流不止啊!婚攝大哥也很敬業,就把那個瞬間捕捉下來了。 後來也是因為工作上的需求,有嘗試過有各種行動剪輯軟體來完成一些小短片,所以還
Thumbnail
倘若你有參加先前在 Matters Lab Discord 辦的資安課,以及我設計的資安小問答,就會知道以資訊安全來說,「傳統電腦」確實是比「智慧型手機」還更危險的(當然前提是都有在更新作業系統)。關於這部分的討論,就不再贅述。
Thumbnail
倘若你有參加先前在 Matters Lab Discord 辦的資安課,以及我設計的資安小問答,就會知道以資訊安全來說,「傳統電腦」確實是比「智慧型手機」還更危險的(當然前提是都有在更新作業系統)。關於這部分的討論,就不再贅述。
Thumbnail
你是否曾因視訊開會沒人發言而感到困擾,又或是想要同時可以共享兩個以上的螢幕?不管是 EP0.2 提過的 Zoom、Webex,抑或微軟的 Teams 和谷歌的 Meet 皆為付費軟體,均需綁定帳號及一連串設定;而本篇文章要帶你了解的是毋須註冊、用電腦也不用下載軟體的免費工具 Jitsi Meet。
Thumbnail
你是否曾因視訊開會沒人發言而感到困擾,又或是想要同時可以共享兩個以上的螢幕?不管是 EP0.2 提過的 Zoom、Webex,抑或微軟的 Teams 和谷歌的 Meet 皆為付費軟體,均需綁定帳號及一連串設定;而本篇文章要帶你了解的是毋須註冊、用電腦也不用下載軟體的免費工具 Jitsi Meet。
Thumbnail
科技成長股有很多細分的板塊,像是SaaS軟體股、金融科技股,電商股、廣告科技股、社交媒體股,等等。最近這一輪跌市看下來,即使整體都比較慘,但當中還是以SaaS軟體股相對抗跌,算是科技成長股當中的「疾風勁草」。
Thumbnail
科技成長股有很多細分的板塊,像是SaaS軟體股、金融科技股,電商股、廣告科技股、社交媒體股,等等。最近這一輪跌市看下來,即使整體都比較慘,但當中還是以SaaS軟體股相對抗跌,算是科技成長股當中的「疾風勁草」。
Thumbnail
今天是除夕,先跟大家說一聲新年快樂!回到美股,我們追蹤股票的財報季也即將展開了,如果是最近才訂閱的讀者可能不清楚,這裡先簡單說明幾句本專欄運作方式......
Thumbnail
今天是除夕,先跟大家說一聲新年快樂!回到美股,我們追蹤股票的財報季也即將展開了,如果是最近才訂閱的讀者可能不清楚,這裡先簡單說明幾句本專欄運作方式......
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News