データベースの各行、APIリソース、分散イベントのそれぞれにIDが必要です。問題はIDを生成することではなく、6ヶ月後にPostgresのインデックスがフラグメント化され、URLがノイズのように見えることへの対応です。
ここに完全な UUID生成器の比較: UUID v4、UUID v7、ULID、CUID2、Snowflake — それぞれの特徴、限界、そして実際に使うべきもの。
UUID v4: 安全なデフォルト(ただし大きな問題あり)
UUID v4は128ビットのランダム性を持ち、次のようにフォーマットされています。 550e8400-e29b-41d4-a716-446655440000。すべての言語、すべてのデータベース、すべてのORMで認識され、サポートされています。
衝突確率は実際にはゼロです — 1秒あたり10億個のUUIDを生成して85年間続けた場合、50%の衝突確率に達するまでに必要なのは現実的ではありません。
問題は順序です。UUID v4は 完全にランダムです。そのため、UUIDインデックス付きのテーブルにデータを挿入するとBツリーに書き込みが散逸します。スケーラビリティが高くなると、ページスプリット、インデックスのフラグメント化、挿入パフォーマンスの低下が発生します。MySQLまたはPostgresのテーブルにUUIDプライマリキーで数千件の行を1秒間に挿入する場合、その影響を実感します。
UUID v4は文字列として36文字です — URL安全ではないためエンコードが必要で、他の選択肢に比べて大きすぎます。
UUID v7: UUID v4のより優れた兄弟
UUID v7は順序問題を解決します。最も重要なビットにミリ秒タイムスタンプを、残りはランダム値をエンコードした時間順のUUIDです。その結果: 01875f3a-7b2d-7f8e-a3d1-4b2e6c1a0f93.
時間順に挿入された行はインデックス内でほぼ連続的に並びます。書き込み負荷の高いワークロードにとって大きなメリットです。UUID v7は既存のUUIDインフラと互換性があり、同じフォーマット、同じフィールド長、同じライブラリサポート要件を維持しながら、並べ替え可能になります。
RFCは2022年に最終決定され、ライブラリサポートは急速に追いついています。既にUUIDを使用していてスキーマを変更できない場合、v4からv7への移行はリスクが低い高報酬の選択です。
ULID: 最も開発者に優しい選択肢
ULID(ユニバーサルにユニークで辞書順に並べられる識別子)は48ビットのタイムスタンプと80ビットのランダム性を26ビットのBase32文字でエンコードします: 01ARZ3NDEKTSV4RRFFQ69G5FAV.
その特徴は:
- デフォルトで並べ替え可能 — 辞書順は時系列順に相当
- URL安全 — ハイフンや特別文字なし
- 大文字と小文字を区別しない — その文字をアルファベットから除外することで曖昧性を回避
0/Oと1/I— 26文字(UUID文字列の36文字より短い) - コンパクト 新しいプロジェクトで古くからの制約がない場合、ULIDは最も実用的な選択です。ほとんどの用途で並べ替え可能で、URLに短く、人間がコピー&ペーストしても誤認を起こさないほど読みやすいです。
ただし、1ミリ秒内に複数のULIDを生成した場合、プロセス内では単調な並べ替えが保証されますが、分散ノード間では保証されません。ほとんどのアプリケーションでは問題ありません。
CUID2: 分散システム向けに設計された
CUID2はCUIDの後継で、セキュリティと分散環境における衝突耐性を新たに設計されました。CUID2は次のようになります:
SHA-3ハッシュを、タイムスタンプ、カウンター、フィンガープリント(プロセスID+ホスト名)、ランダムバイトの組み合わせで生成します。フィンガープリントが鍵です — 複数のノードで同時にIDを生成する場合に衝突を防ぐために特別に設計されています。 clh3uj5ln0000qzrmn831mbhe.
CUID2は
並べ替え可能ではありません 。時間順の並べ替えよりも衝突耐性と予測不可能性を優先します。信頼できないクライアントまたは多数の独立したノードでIDを生成する場合、セキュリティが重要な場合はCUID2はその代償を払う価値があります。ほとんどのバックエンドAPIでは過剰です。
Snowflake ID: 高スループットだが、自分で対応が必要
Snowflake IDは、Twitterで100万件/秒のスケールで分散クラスタでユニークなIDを生成するために開発されました。Snowflake IDは64ビットの整数で、タイムスタンプ(41ビット)+データセンターID(5ビット)+マシンID(5ビット)+シーケンス(12ビット)です。
並べ替え可能で、コンパクト(1バイトに収まる)で非常に高速です。Discord、Instagram、そして多くの高スケールシステムがこのパターンを使用しています。
ただし、マシンIDを管理する必要があります。つまり、ZooKeeper、etcd、またはデータベーステーブルのようなコアサービスを使って、各ID生成器にユニークなマシンIDを割り当てなければなりません。2つのノードが同じマシンIDを持つ場合、衝突が発生します。その設定を正確に実装するのは非自明で、維持には運用負荷がかかります。 BIGINT10万件/秒以上のIDを生成する場合でなければ、その複雑さは価値をもたらしません。
比較
UUID v7
CUID2
| UUID v4 **UUID**は**バージョン4**のものです。 | Snowflake | ULID | 並べ替え可能 | いいえ(ハイフンなし) | |
|---|---|---|---|---|---|
| はい(整数) | いいえ | はい | はい | いいえ | はい |
| URL安全 | 非常に高い | 非常に高い | はい | はい | 高い(コアサービスが必要) |
| 衝突耐性 | 典型的な使用ケース | 典型的な使用ケース | 高い | 典型的な使用ケース | 古くからのシステム、一般用途 |
| 複雑 | なし | なし | なし | 低い | 高い |
| DBのプライマリキー | API、URL、新規プロジェクト | 信頼できない分散クライアント | 高スループットシステム | Node.jsで各IDを生成する方法 | UUID生成を直接テストできます。IO Tools UUID生成器を使用できます。 |
IO Tools UUID生成器
// UUID v4
import { v4 as uuidv4 } from 'uuid';
console.log(uuidv4()); // '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
// UUID v7
import { v7 as uuidv7 } from 'uuid';
console.log(uuidv7()); // '01875f3a-7b2d-7000-8000-4b2e6c1a0f93'
// ULID
import { ulid } from 'ulid';
console.log(ulid()); // '01ARZ3NDEKTSV4RRFFQ69G5FAV'
// CUID2
import { createId } from '@paralleldrive/cuid2';
console.log(createId()); // 'clh3uj5ln0000qzrmn831mbhe'
// Snowflake (using @socialgouv/nextid for simplicity)
import Snowflake from '@socialgouv/nextid';
const snowflake = new Snowflake(1n); // machine ID = 1
console.log(snowflake.nextId().toString()); // '1641024000000000001'
— UUID v1からv7までサポートし、インストールなしでブロック生成が可能です。 どのものを使うべきですか? ここに実際の推奨案、単に「それは depends」という回避策ではなく:
新規プロジェクトで、古くからの制約がない場合:
。並べ替え可能、URL安全、コンパクトです。これは最も適したデフォルトです。
- 既にUUIDを使用しており、DBパフォーマンスを改善したい場合: プレビューするには ULIDに移行してください。ドロップインアップグレードで、インデックスパフォーマンスが劇的に向上します。
- クライアントまたは信頼できない分散ノードでIDを生成する場合: 。フィンガープリントにより、攻撃的な状況でも衝突耐性が強固になります。 Snowflake高スループットプラットフォーム(10万件/秒以上)で、マシンIDを管理できる場合:
- 。それ以外の場合は無駄です。 プレビューするには 並べ替え可能UUID v4:
- 古くからのコードを維持しており、フォーマットを変更できない場合にのみ使用してください。新しいテーブルでは使用しないでください。 プレビューするには いいえ(ハイフンなし)すべての場面でUUID v4をデフォルトに設定する時代は終わりました。新しい用途ではULIDがデフォルトとなり、既にUUIDを使用している場合はUUID v7へのアップグレードが適切です。一つを選んで進んでください。
- UUID v4: もしあなたが古くからのコードを維持していて、フォーマットを変更できない場合に限り、使用してください。新しいテーブルでは使用しないでください。
すべてに対してUUID v4をデフォルトとする時代は終わりです。ほとんどのケースではULIDが新しいデフォルトになります。すでにUUIDを使用している場合は、UUID v7へのアップグレードが適切です。一つを選んで進んでください。
あなたも好きかもしれません
恵 スコアボードが到着しました!
スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!
