sequential_uuid は、シーケンスまたはタイムスタンプに基づいた順序付き UUID 生成ツールを提供します。これにより、ランダム UUID 生成ツールによるランダム入出力問題を軽減できます。
前提条件
次のエンジンを実行する PolarDB for PostgreSQL(Oracle 互換) クラスタで利用できます。
PolarDB for PostgreSQL(Oracle 互換) 2.0 (カーネルバージョン 2.0.14.1.0 以降)
PolarDB for PostgreSQL(Oracle 互換) 1.0 (カーネルバージョン 1.1.28 以降)
次の文を実行して、PolarDB for PostgreSQL(Oracle 互換) クラスタのカーネルバージョンを確認できます。
SHOW polar_version;背景情報
ランダム UUID:特定範囲内で均等な値で生成されます。
デメリット:データの挿入時に、葉ノードに対応するすべてのページがヒットする確率が同じになり、さらにインデックス全体がメモリに格納されるようになります。また、インデックスのサイズが共有バッファまたは RAМ のサイズを超えると、キャッシュヒット率が急速に低下します。
順序付き UUID:シーケンスに基づくタイプと、タイムスタンプに基づくタイプに分けられます。
メリット:ランダム UUID に比べ、順序付き UUID 生成ツールに基づいて生成される UUID は順序性を持ちます。新しいデータは、シーケンス値またはタイムスタンプが一番大きいため、いつもインデックスの一番右に挿入されます。これにより、キャッシュヒット率が向上します。詳細については、「Sequential UUID Generators」をご参照ください。
デメリット:ランダム性が減少し、UUID の予測可能性とマシン間の UUID 衝突の確率が高まります。
sequential_uuid は、UUID の順序性を実現しながら、ランダム性を一定範囲内に控えられます。
生成ツールの仕組み
UUID の構造
順序付き UUID を生成する簡単な方法として、シーケンスまたはタイムスタンプをプレフィックスとして、UUID のランダム性が 16 B に達するまでランダムデータを追加することが考えられます。
しかし、この方法には次の 2 つの問題が発生します。
ランダム性の低下:
bigint 値を生成するシーケンスを使用すると、UUID 生成のランダム性が 16 B から 8 B に減少します。タイムスタンプもその精度に応じてランダム性を低下させます。これによって、衝突リスクと予測可能性 (相前後して生成された UUID の予測、タイムスタンプの予測など) が上昇します。
インデックスの肥大化:
値が大きくなり続けると、履歴データが削除された後にインデックスが肥大化する可能性があります (ログテーブルのタイムスタンプインデックスなど)。
上記の 2 つの問題を解決するために、順序付き UUID 生成ツールでは、ラップアラウンドが定期的に実行されます。
ラップアラウンド
ラップアラウンドとは、処理可能な UUID 範囲の最後に達した後に、最初に戻ることです。順序付き UUID 生成ツールでは、指定された数の UUID が生成された際、または一定期間が経過した際に、ラップアラウンドが実行されます。
UUID はブロック単位で、次の形式で生成されます:
(ブロック ID;ランダムデータ)ブロック ID のサイズはブロックの数によって異なり、生成ツールのパラメータによって決定されています。たとえば、デフォルトのブロック数が 64 K (64*1024=65536) の場合、ブロック ID を格納するために 2 バイトが必要です。
ブロック ID の計算式:
シーケンスに基づく UUID 生成ツール (各ブロックに 256 の UUID が含まれる)
(nextval('s') / 256) % 65536説明ラップアラウンドのサイクル:16 М (256×65536) の UUID が生成されたたび
ブロックサイズ:生成された UUID の数により異なります
タイムスタンプに基づく UUID 生成ツール
(timestamp / 60) % 65536説明ラップアラウンドのサイクル:45 日
ブロックサイズ:間隔です。デフォルト値: 60 秒
UUID 生成関数
シーケンスに基づく UUID 生成ツール
uuid_sequence_nextval 関数を使用し、次のパラメーターを受け入れます。
regclass 型のオブジェクト(シーケンス)。
integer 型のブロックサイズ(デフォルト値 65536)。
integer 型のブロック数(デフォルト値 65536)。
構文:
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 生成ツール
uuid_time_nextval 関数を使用し、次のパラメーターを受け入れます。
integer 型の時間間隔(デフォルト値 60)。
integer 型のブロック数(デフォルト値 65536)。
構文:
CREATE EXTENSION sequential_uuids;
SELECT uuid_time_nextval(1, 256);出力例:
uuid_time_nextval
--------------------------------------
08dac705-8776-4ce3-a45c-123fd65e11e8
(1 row)上記のデフォルト値は、ほとんどのシナリオに適用できます。