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> |
然後我們可以使用以下命令生成 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 就很有意義。