全部產品
Search
文件中心

PolarDB:sequential_uuid(UUID產生)

更新時間:Oct 29, 2024

sequential_uuid外掛程式可以產生兩個具有順序模式的UUID產生器,可以協助您減少完全隨機的UUID產生器所帶來的隨機I/O問題。

前提條件

支援的PolarDB PostgreSQL版(相容Oracle)的版本如下:

  • Oracle文法相容 2.0(核心小版本2.0.14.1.0及以上)

  • Oracle文法相容 1.0(核心小版本1.1.28及以上)

說明

您可通過如下語句查看PolarDB PostgreSQL版(相容Oracle)的核心小版本號碼:

SHOW polar_version;

背景資訊

常規的隨機UUID產生器將在給定的範圍內均勻取值,這意味著向索引插入資料時,其局部性較差,所有索引葉所在的頁都有同樣的機率被命中,從而導致整個索引會被強制放入記憶體中。當使用小索引不會存在這個問題,但一旦索引大小超過共用緩衝區(或者RAM)大小,快取命中率就會迅速下降。

基於序列、時間戳記的UUID與隨機UUID相比,前者具有順序模式,可以使新資料幾乎總是在索引的最右側插入(新的序列值大於所有先前的值,時間戳記相同),從而有利於提升快取命中率。

說明
  • 具有順序模式的UUID產生器增加了UUID的可預測性,且增大了發生跨機衝突的機率。

  • 更多順序UUID優勢請參見Sequential UUID Generators

sequential_uuid的主要目標是產生更具順序性的UUID產生器,且不會過多地降低隨機性(隨機性降低可能會增加碰撞的機率以及UUID的可預測性)。

產生器設計

使UUID更具順序性最簡單的方法是使用一些順序值作為首碼。例如,可以採用序列或時間戳記並添加隨機資料,直到UUID的隨機性達到16 B。這種方法得到的UUID幾乎是完全連續的,但這種方法存在以下兩個問題:

  • 隨機性減少:如果使用了產生bigint值的序列,產生UUID的隨機性將從16 B降低到8 B,時間戳記也以類似的方式降低了隨機性,具體取決於時間戳記的精度。隨機性的下降增加了碰撞機率和可預測性(比如,可以確定哪些UUID是彼此靠近產生的,甚至還可以推測出具體的時間戳記)。

  • 膨脹:如果數值持續增長,可能會導致刪除歷史資料後索引膨脹,例如,日誌表中對時間戳記的索引。

為瞭解決這兩個問題,sequential_uuid產生的UUID產生器被設計為定期迴環,迴環將發生在產生一定數量的UUID之後,或者在一段時間之後。在這兩種情況下,UUID都是以塊為單位產生的,形式為(塊 ID; 隨機資料)。塊ID的大小取決於塊的數量,並且是固定的(取決於產生器參數)。例如,對於預設值64 KB的塊數量,需要使用2個位元組來儲存塊ID。塊ID定期增加,最終會發生迴環。

  • 基於序列的UUID產生器可以使用帶有256個UUID的塊,計算兩位元組塊ID:

    (nextval('s') / 256) % 65536
    說明
    • 產生器每產生16 M(256*65536)個UUID會迴環一次。

    • 塊大小由產生的UUID的數量決定。

  • 基於時間戳記的UUID產生器預設的塊數量是64 KB(與基於序列的產生器相同),計算塊ID:

    (timestamp / 60) % 65536
    說明
    • 產生器約45天迴環一次。

    • 塊大小被定義為間隔長度,預設值為60秒。

UUID產生函數

sequential_uuid提供了兩個產生具有順序模式的UUID產生器的函數。一個使用序列,一個使用時間戳。

  • 函數uuid_sequence_nextval接收如下參數:

    • 一個regclass類型的對象(序列)。

    • 一個整數類型的塊大小(預設值65536)。

    • 一個整數類型的塊數量(預設值65536)。

    使用序列產生具有順序模式的UUID產生器:

    CREATE EXTENSION sequential_uuids;
    CREATE SEQUENCE s;
    SELECT uuid_sequence_nextval('s'::regclass, 256, 65536);

    結果如下:

              uuid_sequence_nextval
    --------------------------------------
     00005547-8a67-452d-bdf7-b390f1edc49b
    (1 row)
  • 函數uuid_time_nextval接收如下參數:

    • 一個整數類型的時間間隔(預設值60)。

    • 一個整數類型的塊數量(預設值65536)。

    使用時間戳產生具有順序模式的UUID產生器:

    CREATE EXTENSION sequential_uuids;
    SELECT uuid_time_nextval(1, 256);

    結果如下:

              uuid_time_nextval
    --------------------------------------
     08dac705-8776-4ce3-a45c-123fd65e11e8
    (1 row)
說明

上述參數的預設值適用於絕大部分情境。