カテゴリー
アーカイブ

10.02
2025

PostgreSQL 18 で追加された uuidv7() 関数を試す

  • LINE

はじめに

2025年9月25日に PostgreSQL 18 がリリースされました。(日本語版のプレスリリース

今回の記事では、UUID v7 を生成する関数 uuidv7() が標準でサポートされたことに注目してみます。

UUID v7 は、時系列ソートが可能な UUID であり、ミリ秒までのタイムスタンプと乱数を組み合わせて生成されます。
UUID v4 と比較し、インデックス効率の向上やログ管理の改善が期待できます。

これまで UUID v7 を使用する場合はアプリケーション側で生成するなどの対応が必要でしたが、PostgreSQL 18 では DB 側で自動生成できるようになりました。
これにより、アプリケーションコードをよりシンプルに保ちながら UUID v7 を扱えるようになります。

本記事では実際に PostgreSQL 18 上で uuidv7() を使用し、UUID v7 を自動生成できることを確認していきます。

予備知識

UUID とは

UUID(Universally Unique Identifier)は、その名の通り「ほぼ衝突しない一意な識別子」を生成する仕組みです。
128 ビット(16 バイト)の固定長データで表され、一般的にはハイフン区切りの 36 文字の文字列として扱われます。

例:

550e8400-e29b-41d4-a716-446655440000

UUID のメリットは、他のシステムやノードと調整することなく一意な値を生成できる点です。
これにより、分散環境やマイクロサービス間での ID 採番、DB のプライマリキーなどに広く利用されています。

UUID にはいくつかのバージョンがあり、用途や生成方法に応じて使い分けが行われます。代表的なものが UUID v4 と、今回 PostgreSQL 18 で新たにサポートされた UUID v7 です。

UUID v4 と UUID v7 の違い

・UUID v4
 ・ランダム値をベースに生成されるバージョン。
 ・生成が非常にシンプルで、衝突の可能性はほぼゼロ。
 ・ただし完全にランダムなため、ソート順が生成時刻と無関係。
 ・DB インデックスを利用する際に、ランダム挿入が多発してフラグメント化しやすい欠点がある。

・UUID v7
 ・2024 年5月に RFC9562標準化された新しいバージョン。
 ・タイムスタンプ(ミリ秒単位)+ランダム値を組み合わせて生成。
 ・先頭ビットに時間情報を持つため、生成された UUID を並べるとほぼ時系列順になる。
 ・DB のインデックスが順序性を保ちやすくなり、挿入性能やクエリ効率が改善される。
 ・ログやイベント ID としても、時系列の見通しが良くなる。

UUID v7 の例:

01999de5-2dd8-7755-ab25-dc97549fb6f0

上位 48 ビット(12文字)分が UNIX ミリ秒となっており、変換によって実際に時刻が分かります。

01999de52dd8 (16進数)1759290666456 (10進数)2025-10-01T12:51:06.456+09:00

 

UUID について分かりやすくまとめられた記事のリンクを「参照資料」欄に記載しました。
詳しく知りたい方はこちらを参照ください。

 

動作確認

docker を使用して PostgreSQL 18 のコンテナを起動します。

init.sql の中で、uuidv7()id を自動生成する users テーブルを作成しています。

# compose.yml
services:
  postgres:
    image: postgres:18
    container_name: postgres
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_HOST_AUTH_METHOD: trust
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:
# init.sql
CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT uuidv7(),
    name VARCHAR(255) NOT NULL
);

name のみを指定して users に INSERT 後、SELECT してみます。

$ docker compose exec postgres psql -U user -d mydb
> INSERT INTO
    users (name)
VALUES
    ('John Doe'),
    ('Jane Smith');
INSERT 0 2

> INSERT INTO
    users (name)
VALUES
    ('Bob Johnson');
INSERT 0 1

> SELECT id, name FROM users ORDER BY id;
                  id                  |    name     
--------------------------------------+-------------
 01999de5-2dd8-7755-ab25-dc97549fb6f0 | John Doe
 01999de5-2dd8-7c79-8bd6-86d90c9dc720 | Jane Smith
 01999de5-4536-7d4c-9ccf-b3dea13d37d6 | Bob Johnson
(3 rows)

id が UUID v7 形式で自動生成されており、INSERT した順に昇順となっていることが確認できました。

 

おわりに

PostgreSQL 18 から標準関数として uuidv7() を利用できるようになったことで、これまで以上に手軽に UUID v7 を導入できるようになりました。

今後は UUID v4 の代替として、UUID v7 の採用を積極的に検討していきたいと思います。

 

参考資料

1. 七夕だからUUID v7について語る #rfc - Qiita

2. UUID v7 のデータ構造を詳細に理解する

3. RFC 9562: Universally Unique IDentifiers (UUIDs)

"全員が技術者" ベイストリームは横浜発のPythonのプロフェッショナル集団です。
積極採用中!尖ったPythonエンジニアへの第一歩はこちらから