ブログに戻る

ランダムUUIDがデータベースパフォーマンスに与える影響

5 min read 分で読める
DatabasePerformanceUUIDArchitecture

背景

以前の大学のセメスターで、ReactとFirebaseを使用した基本的なライブ出席ツールという最終プロジェクトに取り組んでいた際、プロジェクト評価者からUUIDv4を使用したデータベースインデックスに対する不満のフィードバックを受けたことを覚えています。この批評は特定の技術的な問題によるものでした。数年後、最近Hussein Nasserのビデオを見つけ、彼がUUIDv4に関連する問題を説明していて、プロジェクト評価中に提起された懸念に光を当てました。

UUIDとは?

UUID(Universally Unique Identifiers)は、中央機関を必要とせずにコンピュータシステムで情報を一意に識別するために使用される128ビットの識別子です。通常、ハイフンで区切られた5つのグループ(8-4-4-4-12)で表示される32個の16進数で構成されています。

データベースでは、UUIDはその固有の一意性のためにプライマリキーとしてよく使用されます。分散システムで競合を引き起こす可能性がある増分整数とは異なり、UUIDは信頼性の高いソリューションを提供します。

UUIDの異なるバージョン(1〜5)は、一意の識別子を生成するためにさまざまなアルゴリズムとソースを使用します:

  • バージョン1(時間ベース): 現在のタイムスタンプとネットワークインターフェースのMACアドレスから生成
  • バージョン2(DCEセキュリティ): バージョン1に似ていますがPOSIX UID/GID値を使用
  • バージョン3(名前ベース、MD5): 名前空間と名前のMD5ハッシュを使用して生成
  • バージョン4(ランダム): 乱数または擬似乱数を使用して生成
  • バージョン5(名前ベース、SHA-1): バージョン3に似ていますがより安全なSHA-1ハッシュアルゴリズムを使用

人気のUUIDv4(とその問題)

すべてのUUIDバージョンの中で、UUIDv4はランダム性から派生した高い一意性の確率のため、データベースのプライマリキーとして最も人気があります。しかし、これには代償が伴います。

UUIDv4値をプライマリキーとして使用することの影響を理解するには、InnoDBがデータをどのように整理するかを調べることが重要です。InnoDBはテーブルの行をプライマリキーのB-tree内に整理します。これはクラスタードインデックスと呼ばれます。

ランダムに生成されたプライマリキー値を持つ新しい行が挿入されると、InnoDBは一連のアクションを実行します。完全にランダムな値と大規模なテーブルのシナリオでは、すべてのB-treeリーフページが新しい行を受け取る可能性があり、特定の「ホットページ」がありません。

UUID V7とULID

UUIDv7とULIDは、UUIDv4によって引き起こされる課題のいくつかに対処することを目的としています:

  • UUIDv7: このバージョンのUUIDは、時間に基づいたソート可能な機能を導入することを提案しています。純粋にランダムなUUIDv4とは異なり、UUIDv7は識別子を生成するために時間ベースの要素を組み込み、時系列順序付けを可能にします。

  • ULID(Universally Unique Lexicographically Sortable Identifier): ULIDは識別子生成への異なるアプローチです。ランダム性と時間コンポーネントを組み合わせて、一意かつソート可能な識別子を作成します。

実際のユースケース(Shopify ULIDケース)

2022年7月28日、Shopifyエンジニアリングは「Building Resilient Payment Systems」という記事を公開し、彼らがULIDを冪等性キーとしてどのように使用しているかを説明しました。彼らはULIDを使用することでデータベース書き込み操作速度を50%改善したと主張しています。

これは、UUIDv4からULIDへの切り替えが、数百万のトランザクションを処理する大規模な本番システムで大幅なパフォーマンス改善をもたらした実際のアプリケーションを示しています。