モデルのデータを非正規化する

完了

このユニットでは、リレーショナル データベースの product テーブルを確認し、それを NoSQL データベース用にモデル化します。 また、製品テーブルと製品タグとの 多対多の 関係も確認します。

製品と製品タグ エンティティの関係を示す図。

製品エンティティをモデル化する

product テーブルの初期モデルには、リレーショナル テーブルのフィールドのみが含まれています。 ただし、e コマース アプリケーションでは、製品ページを表示するときに製品カテゴリ名を表示する必要があります。 また、製品カテゴリ内の製品タグによってクエリも実行します。 これを行うには 2 つの方法があります。製品を製品タグ コンテナーに格納する方法と、タグを製品コンテナーに埋め込む方法です。

製品ごとのタグの数がタグあたりの製品の数よりはるかに少ない場合は、製品テーブルに製品タグを埋め込むことをお勧めします。 各製品とタグの間には 一対少数 の関係があるため、埋め込みには適しています。 また、新しい製品コンテナーには、製品データと共に埋め込まれたタグを格納します。 そのため、新しい製品モデルは次の図のようになります。

製品と製品タグ エンティティの関係を示す図。また、まだパーティション キーを選択していない製品コンテナーも含まれています。

パーティション キーを選択する

次に、製品コンテナーのパーティション キーを選択します。 ここでも、パーティション キーを決定するために実行する操作を確認する必要があります。 製品を作成するか、製品を編集することができます。 顧客は、eコマース サイト内を移動するとき、多くの場合、製品カテゴリを使用して移動します。 categoryId によって製品をフィルター処理してユーザーに表示するクエリが必要です。 クエリをカテゴリ別のすべての製品を含む単一パーティション クエリにするには、categoryId を製品コンテナーのパーティション キーとして使用します。

パーティション キーとして 'categoryId' を持つ製品コンテナーの図、操作の一覧、カテゴリ内のすべての製品を一覧表示する SQL ステートメント。

そのため、categoryId は、カテゴリ内のすべての製品を効率的に取得できる適切なパーティション キーです。 タグ ID を埋め込むと、製品とタグの間の多対多リレーションシップで ID を取得できます。 ただし、製品のクエリを実行する場合は、製品データだけでなく、カテゴリ名とタグ名も表示する必要があります。 製品のクエリを実行するときに、各製品のカテゴリ名と製品タグの名前を取得するにはどうすればよいでしょうか。

現在、カテゴリの製品ページを表示するには、次のクエリを実行する必要があります。

  1. 製品コンテナーのクエリを実行して、カテゴリ内のすべての製品を取得します。
  2. productCategory コンテナーのクエリを実行して、製品カテゴリの名前を取得します。
  3. 次に、最初のクエリによって返されたすべての製品について、productTag コンテナーに対する 3 番目のクエリを実行して、各製品タグの名前を取得します。

product、productCategory、productTag コンテナー、およびカテゴリ操作のすべての製品を一覧表示するために実行するクエリの図。

製品エンティティを非正規化する

前述のすべてのクエリを実行すると、うまくいく可能性があります。 ただし、このアプローチはあまりスケーラブルではありません。 NoSQL データベースでは、コンテナー間に 結合 がないため、結合は選択できないことに注意してください。 また、NoSQL データベースの目的は、できるだけ少ない要求数でアプリケーション データをフェッチできるように、データをモデル化することで要求数を減らすことである点にも注意してください。

その解決策は、データを 非正規化 することです。 非正規化により、データ モデルを最適化し、アプリケーションに必要なすべてのデータをクエリで処理できる状態にすることができます。

この例では、データを非正規化するために、カテゴリの名前やタグ配列の各タグの名前などのプロパティを追加します。 これらのプロパティを追加することで、クライアントに返す必要のあるすべてのデータを 1 回の要求で取得できるようになります。

パーティション キー 'categoryId' を持つコンテナーと、非正規化されたカテゴリ名と製品タグ配列を持つモデル化された製品ドキュメント スキーマの図。