アーカイブ
はじめに
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 の採用を積極的に検討していきたいと思います。
参考資料
積極採用中!尖ったPythonエンジニアへの第一歩はこちらから