データモデリングは、アプリケーションが特定のデータベースにデータを格納する方法を設計するプロセスです。DynamoDB などの NoSQL データベースでは、データモデリングはリレーショナルデータベースを使用したモデリングとは異なります。リレーショナルデータベースは柔軟性のために構築されており、分析アプリケーションに最適です。リレーショナルデータモデリングでは、最初にエンティティから始めます。正規化されたリレーショナルモデルがある場合、アプリケーションで必要なクエリパターンを満たすことができます。

NoSQL (非リレーショナル) データベースは、柔軟性ではなく、速度とスケールのために設計されています。リレーショナルデータベースのパフォーマンスはスケールアップに伴って低下する可能性がありますが、DynamoDB などの水平スケーリングデータベースは、あらゆるスケールで一貫したパフォーマンスを実現します。一部の DynamoDB ユーザーには 100 TB を超えるテーブルがあり、テーブルの読み取りおよび書き込みパフォーマンスは、テーブルのサイズが 1 GB より小さい場合と同じです。

DynamoDB などの NoSQL データベースで最高の結果を達成するには、一般的なリレーショナルデータベースからの考え方の転換が必要です。DynamoDB を使用してデータをモデリングする場合は、次のベストプラクティスに従ってください。

1.アクセスパターンに焦点を当てる
種類を問わず、データモデリングを行う場合、アプリケーションのさまざまなオブジェクト (またはエンティティ) とそれらの接続方法 (またはエンティティ間のリレーションシップ) を説明するエンティティ関係図から始めます。

リレーショナルデータベースでは、エンティティを直接テーブルに配置し、外部キーを使用してリレーションシップを指定します。データテーブルを定義した後、リレーショナルデータベースは、必要な形状のデータを返すための柔軟なクエリ言語を提供します。

DynamoDB では、テーブルをモデル化する前にアクセスパターンについて検討します。NoSQL データベースは、柔軟性ではなく速度に重点を置いています。最初にデータへのアクセス方法を尋ね、次にアクセスする形状でデータをモデル化します。

DynamoDB テーブルを設計する前に、アプリケーションでデータを読み書きするために必要なものすべてを文書化します。アクセスパターンに合わせてテーブルを最適化することになるため、アプリケーションのすべてのフローを徹底的に検討してください。

2.DynamoDB へのリクエスト数を最適化する
アプリケーションのアクセスパターンのニーズを文書化したら、テーブルを設計できます。アクセスパターンごとに DynamoDB へのリクエストの数を最小限に抑えるようにテーブルを設計する必要があります。理想的には、ネットワークリクエストが遅いため、各アクセスパターンに必要な DynamoDB へのリクエストは 1 つだけである必要があります。これにより、アプリケーションで行うネットワークリクエストの数が制限されます。

DynamoDB へのリクエスト数を最適化するには、以下のコアコンセプトを理解する必要があります。

プライマリキー
セカンダリインデックス
トランザクション

3.リレーショナルモデルを偽造しないでください
DynamoDB を初めて使用する人は、非リレーショナル DynamoDB の上にリレーショナルモデルを実装しようとすることがよくあります。これを行おうとすると、DynamoDB の利点のほとんどが失われてしまいます。

DynamoDB で試す最も一般的なアンチパターン (繰り返し発生する問題に対する効果のない応答) は次のとおりです。

  •  正規化: リレーショナルデータベースでは、データを正規化してデータの冗長性とストレージスペースを削減し、ジョインを使用して複数の異なるテーブルを結合します。ただし、大規模なジョインは遅く、高価です。DynamoDB は、テーブルが大きくなるにつれて速度が低下するため、ジョインを許可しません。
  • テーブルごとに 1 つのデータ型: 多くの場合、DynamoDB テーブルには単一のテーブルにさまざまなタイプのデータが含まれます。この例では、1 つのテーブルに User、Game、および UserGameMapping エンティティがあります。リレーショナルデータベースでは、これは 3 つの異なるテーブルとしてモデル化されます。
  • セカンダリインデックスが多すぎる: ユーザーはよく、必要な追加のアクセスパターンごとにセカンダリインデックスを作成しようとします。DynamoDB はスキーマレスであり、これはインデックスにも適用されます。属性の柔軟性を使用して、テーブル内の複数のデータ型にかけて単一のセカンダリインデックスを再利用します。これはインデックスのオーバーロードと呼ばれます。

以下の手順では、エンティティ関係図を作成し、アクセスパターンを事前にマッピングします。DynamoDB を使用する場合、これらが常に最初のステップになります。次に、後続のモジュールで、このアクセスパターンをテーブルデザインに実装します。

モジュールの所要時間: 20 分


  • ステップ 1: エンティティ関係図を作成する

    データモデリング演習の最初のステップは、アプリケーション内のエンティティとそれらの相互関係を示す図を作成することです。

    このアプリケーションには、次のエンティティがあります。
    • User
    • Game
    •UserGameMapping

    User エンティティは、アプリケーションのユーザーを表します。ユーザーは複数の Game エンティティを作成できます。ゲームの作成者は、プレイするマップとゲームの開始時期を決定します。User は複数の Game エンティティを作成できるため、UserGame の間には 1 対多のリレーションシップがあります。

    最後に、Game には複数の User が含まれ、User は時間をかけて複数の異なる Game をプレイできます。したがって、UserGame の間には多対多のリレーションシップがあります。このリレーションシップは UserGameMapping エンティティで表すことができます。

    これらのエンティティとリレーションシップを念頭に置いて、エンティティ関係図を以下に示します。

    Module2-step1

    (クリックして拡大)

    Module2-step1
  • ステップ 2: ユーザープロファイルのアクセスパターンを検討する

     ゲームのユーザーは、ユーザープロファイルを作成する必要があります。これらのプロファイルには、ユーザー名、アバター、ゲーム統計、各ユーザーに関するその他の情報などのデータが含まれます。ユーザーがログインすると、ゲームはこれらのユーザープロファイルを表示します。他のユーザーは、ユーザーのプロファイルを表示して、ゲームの統計情報やその他の詳細を確認できます。

    ユーザーがゲームをプレイすると、ゲームの統計が更新され、ユーザーがプレイしたゲーム数、ユーザーが勝ったゲーム数、およびユーザーによるキル数が反映されます。

    この情報に基づいて、次の 3 つのアクセスパターンがあります。

    •  ユーザープロファイルを作成 (書き込み)
    •  ユーザープロファイルを更新 (書き込み)
    • ユーザープロファイルを取得 (読み取り)
  • ステップ 3: ゲーム前のアクセスパターンを検討する

    ここで取り上げるゲームはバトルロワイヤルゲームです。プレイヤーは特定のマップでゲームを作成でき、他のプレイヤーはゲームに参加できます。50 人のプレイヤーがゲームに参加すると、ゲームが開始され、追加のプレイヤーは参加できません。

    参加するゲームを検索するとき、プレイヤーは特定のマップでプレイしたい場合があるかもしれません。他のプレイヤーはマップを気にせず、すべてのマップで開いているゲームを閲覧したいと思うことでしょう。

    この情報に基づいて、次の 7 つのアクセスパターンがあります。

    • ゲームを作成 (書き込み)
    • オープンゲームを見つける (読み取り)
    • マップでオープンゲームを見つける (読み取り)
    • ゲームを見る (読み取り)
    • ゲーム内のユーザーを表示 (読み取り)
    • ユーザーがゲームに参加 (書き込み)
    • ゲームを開始 (書き込み)
  • ステップ 4: ゲーム内およびゲーム後のアクセスパターン

    最後に、ゲーム中およびゲーム後のアクセスパターンを考えてみましょう。

    ゲーム中、プレイヤーは最後のプレイヤーになることを目標に他のプレイヤーを倒そうとします。このアプリケーションは、ゲーム中に各プレイヤーがキルした数と、ゲームでプレイヤーが生き残った時間を追跡します。プレイヤーがゲームで生き残った最後の 3 人の 1 人である場合、そのプレイヤーはそのゲームで金メダル、銀メダル、または銅メダルを受け取ります。

    後で、プレイヤーは自分がプレイした過去のゲーム、または他のプレイヤーがプレイしたゲームを確認したい場合があります。

    この情報に基づいて、次の 3 つのアクセスパターンがあります。

    • ユーザーのゲームを更新 (書き込み)
    • ゲームを更新 (書き込み)
    • ユーザーの過去のすべてのゲームを見つける (読み取り)

    これで、ゲームのすべてのアクセスパターンがマッピングされました。次のモジュールでは、DynamoDB を使用してこれらのアクセスパターンを実装します。

    計画段階では数回の反復が必要になる場合があることに注意してください。アプリケーションに必要なアクセスパターンの一般的な考え方から開始しましょう。テーブルにプライマリキー、セカンダリインデックス、および属性をマップします。最初に戻り、アクセスパターンがすべて満たされていることを確認します。計画段階が完了したと自信が持てたら、実装に進みます。