PostgreSQL中UUID v7作為主鍵

banq發表於2024-07-07


Postgres 有一個專門用於 UUID 的資料型別:uuid。UUID 是 128 位資料型別,因此儲存單個值需要 16 個位元組。

隨機 UUID 不適合 B 樹索引 - 並且 B 樹索引是主鍵唯一可用的索引型別。
B 樹索引最適合有序值 - 例如自動遞增或按時間排序列。

UUID v7適合 B 樹索引
UUID v7是產生按時間排序的值。這意味著每次生成新的 UUID v7 時,它的值都會更大。這使得它非常適合 B 樹索引。

要在 Java 中使用 UUID v7,我們需要一個第三方庫,例如java-uuid-generator:


<dependency>
  <groupId>com.fasterxml.uuid</groupId>
  <artifactId>java-uuid-generator</artifactId>
  <version>5.0.0</version>
</dependency>

然後我們可以使用以下命令生成 UUID v7:

Java 語言

UUID uuid = Generators.timeBasedEpochGenerator().generate();

從理論上來說這應該可以提高執行INSERT語句的效能。

  • 插入 UUID v7比插入常規 UUID v4快約 2 倍。

由於 UUID 長度 - 即使進行了所有這些最佳化,它也不是主鍵的最佳型別。

  • Postgres 17 很可能將原生支援 UUID v7

網友:
1、如果您選擇 UUID 路線,請檢視以下內容:
  • 確保您使用的列型別儲存為 128 位。不要儲存字母、數字和連字元。
  • 檢視 UUID/GUID 的 COMB/順序變體。它將 UTC 當前日期時間中的幾位移入值中,因此它們是連續的,適合索引。

2、本文忽略了一個重要考慮因素,即 B-Tree 索引經常使用鍵壓縮。當您的鍵較小且連續(大多數情況下)時,壓縮效果非常好,索引更密集,因此速度更快。
由於 UUID 比嚴格需要的長得多,並且不太連續,它們包含更多必須在索引中跟蹤的不可壓縮的隨機性,如果不是很連續,還需要更多的樹重新平衡。

3、只需使用 ULID,問題已解決https://github.com/ulid/spec

4、使用整數主鍵供內部使用(連線等),並使用 uuid 索引供公眾使用,或者僅使用 uuid 作為 PK。

5、如果您擁有大量資料行(數百萬),那麼如果表由 FK 引用,則 PK 的 UUID 對每個人都不利,因為索引的大小/雜湊連線的效能會受到很大影響。在我看來,不變的 int PK 適合面向公眾。
如果您沒有很多資料行,那麼自然鍵(如 SSN 或列的組合)對於面向公眾來說非常友好。
 UUID 的唯一用途是支援使用者介面,因為您可以在客戶端為新行生成新的 UUID,這更方便。

6、UUID 的真正用途是整合。假設您有兩家企業,其中一家收購了另一家,而您想要將記錄合併在一起。很簡單,所有東西在兩個系統中都是唯一標識的,不會出現駭客遷移和下游服務中斷的情況。或者假設您有一個離線工作的客戶端,並且希望最終與主伺服器同步,那麼 UUID 就很有意義。
 

相關文章