編程學(xué)習(xí)網(wǎng) > 編程語言 > Python > 放棄使用UUID,ULID才是更好的選擇!
2025
09-29

放棄使用UUID,ULID才是更好的選擇!


我以前寫服務(wù)的時候,習(xí)慣性就用 UUID 來做主鍵或者分布式 ID,感覺挺自然的嘛,Java 里一行 UUID.randomUUID() 就能搞定,Python 里 uuid.uuid4() 也很順手。可是時間長了,問題一個個暴露出來,才發(fā)現(xiàn) UUID 雖然“方便”,但真不一定是最佳選擇。

UUID 的那些小坑

先說 UUID,它是 128 位,通常寫成 36 個字符那種帶橫杠的字符串,比如:


看上去沒啥問題,但問題有幾個:

  1. 太長了:36 個字符,在數(shù)據(jù)庫里當(dāng)主鍵,不管是索引還是存儲,開銷都挺大。
  2. 無序性:UUID 本質(zhì)上是隨機(jī)的(尤其是 v4),寫到數(shù)據(jù)庫里會導(dǎo)致索引亂跳,插入性能直線下降。
  3. 可讀性差:光看 UUID 完全沒法區(qū)分誰先誰后,排個序都不現(xiàn)實。

這些小坑疊在一起,就讓 UUID 在高并發(fā)、大量寫入的業(yè)務(wù)里挺難受。

ULID 登場

后來我接觸到 ULID(Universally Unique Lexicographically Sortable Identifier),說白了,它和 UUID 一樣是全局唯一 ID,但設(shè)計上更貼合實際場景。

ULID 的幾個優(yōu)勢:

  • 長度更短:26 個字符,比 UUID 少一截。
  • 可排序:它的前半部分是基于時間戳生成的,天然有序,插入數(shù)據(jù)庫更友好。
  • 可讀性好:ULID 是 Crockford’s Base32 編碼,不會有大小寫混亂問題,看起來干凈多了。

舉個 Python 的例子,先裝個庫:


然后:


是不是比 UUID 短一些,而且字母數(shù)字組合看起來也沒那么亂。

性能和排序的對比

UUID 在數(shù)據(jù)庫里有個老毛病:因為它隨機(jī),寫入時會讓索引樹不停分裂,寫多了性能直接掉下來。ULID 前半部分是時間戳,天然就順序增長,索引幾乎是線性擴(kuò)展的。

比如你要存一批訂單數(shù)據(jù),用 ULID 作為主鍵,后續(xù)查詢“最近的訂單”,直接 ORDER BY id DESC 就行了;用 UUID 就沒這個優(yōu)勢。

我自己測試的時候,PostgreSQL 下用 UUID 做主鍵,插入幾百萬條后,索引膨脹得厲害,查詢也慢。換成 ULID,性能穩(wěn)得多。

代碼里的應(yīng)用場景

比如建表的時候:


Python 里插入:


這樣每個訂單都有一個可排序、全局唯一的 ID,數(shù)據(jù)庫層面也不會卡。

什么時候該用 ULID?

不是說 UUID 就完全不能用了,如果你是那種“無狀態(tài)、臨時 ID”的場景,用 UUID 隨便搞搞也無所謂。但如果是:

  • 數(shù)據(jù)庫主鍵
  • 日志追蹤 ID
  • 分布式系統(tǒng)里需要唯一 ID 且要排序

那 ULID 基本就是完美替代品。

我現(xiàn)在新項目里基本就不考慮 UUID 了,直接用 ULID,省心省力,還順便優(yōu)化了數(shù)據(jù)庫性能。你要還在用 UUID,當(dāng)心哪天線上寫入卡得你懷疑人生。

以上就是“放棄使用UUID,ULID才是更好的選擇!的詳細(xì)內(nèi)容,想要了解更多Python教程歡迎持續(xù)關(guān)注編程學(xué)習(xí)網(wǎng)。

掃碼二維碼 獲取免費視頻學(xué)習(xí)資料

Python編程學(xué)習(xí)

查 看2022高級編程視頻教程免費獲取