PostgreSQLにおけるUUID
PostgreSQLでのUUID完全ガイド。ネイティブuuid型、gen_random_uuid()、インデックス戦略、ストレージ最適化、拡張機能によるv7生成をコード例付きで解説します。
Usage
詳細な説明
PostgreSQLはUUIDに対するファーストクラスのサポートを備えており、内部的に16バイトで格納する専用の uuid データ型があります。これは可能な限り最も省スペースな表現です。
UUIDカラムの作成:
-- UUID v4 as primary key (PostgreSQL 13+, no extension needed)
CREATE TABLE users (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
email text NOT NULL UNIQUE,
created_at timestamptz DEFAULT now()
);
-- Insert with auto-generated UUID
INSERT INTO users (email) VALUES ('alice@example.com');
-- Insert with explicit UUID
INSERT INTO users (id, email)
VALUES ('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'bob@example.com');
UUID生成関数:
| 関数 | ソース | バージョン |
|---|---|---|
gen_random_uuid() |
組み込み(PG 13+) | v4 |
uuid_generate_v4() |
uuid-ossp拡張 | v4 |
uuid_generate_v1() |
uuid-ossp拡張 | v1 |
uuid_generate_v1mc() |
uuid-ossp拡張 | v1(ランダムMAC) |
| カスタム関数 | PL/pgSQL | v7 |
PostgreSQLでのUUID v7: PostgreSQLにはまだ組み込みのv7ジェネレーターがありませんが、PL/pgSQLで作成できます:
CREATE OR REPLACE FUNCTION uuid_generate_v7() RETURNS uuid AS $$
DECLARE
unix_ts_ms bigint;
uuid_bytes bytea;
BEGIN
unix_ts_ms = (extract(epoch from clock_timestamp()) * 1000)::bigint;
uuid_bytes = set_byte(
set_byte(
overlay(
uuid_send(gen_random_uuid())
placing substring(int8send(unix_ts_ms) from 3)
from 1 for 6
),
6, (get_byte(uuid_send(gen_random_uuid()), 6) & 15) | 112
),
8, (get_byte(uuid_send(gen_random_uuid()), 8) & 63) | 128
);
RETURN encode(uuid_bytes, 'hex')::uuid;
END
$$ LANGUAGE plpgsql VOLATILE;
あるいは、pg_uuidv7 拡張機能がネイティブC実装によるより高いパフォーマンスを提供します。
インデックスパフォーマンス:
-- B-tree index (default for PRIMARY KEY)
-- Works well with UUID v7 (sequential), poorly with UUID v4 (random)
CREATE INDEX idx_users_id ON users (id);
-- BRIN index (Block Range Index) — excellent for UUID v7
-- Much smaller than B-tree, ideal for append-mostly tables
CREATE INDEX idx_events_id ON events USING BRIN (id);
-- Hash index — O(1) lookups, no range scans
-- Smaller than B-tree, good for equality-only queries
CREATE INDEX idx_sessions_id ON sessions USING HASH (id);
ストレージ比較:
| 型 | カラムサイズ | 1000万行のインデックス |
|---|---|---|
| uuid | 16バイト | 約350 MB |
| bigint | 8バイト | 約175 MB |
| text(36) | 40バイト | 約750 MB |
PostgreSQLでの便利なUUID操作:
-- Cast string to UUID
SELECT '550e8400-e29b-41d4-a716-446655440000'::uuid;
-- Extract timestamp from UUID v7 (approximate)
SELECT to_timestamp(
('x' || lpad(left(id::text, 8) || substr(id::text, 10, 4), 12, '0'))::bit(48)::bigint / 1000.0
) FROM events;
ユースケース
PostgreSQLのネイティブUUID型は、行レベルセキュリティポリシーとUUIDを使用したテナント間データ分離を共有データベーススキーマで実現するマルチテナントSaaSアプリケーションの基盤です。