7月6日、MACIEJ WALKOWIAK氏が「PostgreSQLとUUIDをプライマリキーとして使用する方法」と題した記事を公開し、注目を集めている。この記事では、UUIDをPostgreSQLのプライマリキーとして効率的に使用する方法について詳しく紹介されている。
UUIDの概要
UUIDは一意性が保証され、分散システム間で容易に共有できるため、データベースのプライマリキーとしてよく使用される。ただし、UUIDのサイズを考慮すると、その選択が正しいかどうかは疑問の余地がある。この記事では、UUIDが適切かどうかではなく、どのようにPostgreSQLで効率的に使用するかに焦点を当てている。
Postgresのデータ型
UUIDは文字列として見なすことができ、text
データ型を使用して保存することも可能だが、Postgresには専用のuuid
データ型があり、これは128ビットのデータ型である。以下のSQLコードは、text
とuuid
を使用した2つのテーブルを作成する例である。
create table bank_transfer(
id text primary key
);
create table bank_transfer_uuid(
id uuid primary key
);
text
型のテーブルは54%大きく、インデックスサイズも85%大きい。この違いは、小さなテーブルでは重要でないが、数十万から数百万行のデータを保存する際には問題になる。
UUIDとB-Treeインデックス
ランダムなUUIDはB-treeインデックスには適していない。B-treeインデックスは、順序付けられた値と最も相性が良い。完全にランダムなUUID v4に比べ、UUID v7は時系列順の値を生成するため、B-treeインデックスと良い組み合わせになる。JavaでUUID v7を使用するには、以下のようにサードパーティライブラリが必要である。
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>5.0.0</version>
</dependency>
UUID uuid = Generators.timeBasedEpochGenerator().generate();
UUID v7の挿入パフォーマンスへの影響
UUID v7を使用する新しいテーブルを作成し、10000
行のデータを10
回挿入して、時間を測定した結果、UUID v4に比べ、UUID v7の挿入が約2倍速いことが確認された。
create table bank_transfer_uuid_v7(
id uuid primary key
);
for (int i = 1; i <= 10; i++) {
measure(() -> IntStream.rangeClosed(0, 10000).forEach(it -> {
jdbcClient.sql("insert into bank_transfer (id) values (:id)")
.param("id", UUID.randomUUID().toString())
.update();
}));
measure(() -> IntStream.rangeClosed(0, 10000).forEach(it -> {
jdbcClient.sql("insert into bank_transfer_uuid (id) values (:id)")
.param("id", UUID.randomUUID())
.update();
}));
measure(() -> IntStream.rangeClosed(0, 10000).forEach(it -> {
jdbcClient.sql("insert into bank_transfer_uuid_v7 (id) values (:id)")
.param("id", Generators.timeBasedEpochGenerator().generate())
.update();
}));
}
まとめ
UUIDの長さを考慮すると、最適なプライマリキーの型ではないが、UUIDを使用する場合、上記の最適化を考慮することが重要である。詳細はPostgreSQL and UUID as primary keyを参照していただきたい。
The random events in bitlife 2 make every playthrough unique. You’re constantly challenged with unexpected situations that keep you on your toes.
Every unique and primary key needs to have its duplicates papa's games checked at INSERT.