モデルのデータを非正規化する
このユニットでは、リレーショナル データベースの product テーブルを確認し、それを NoSQL データベース用にモデル化します。 また、product テーブルと製品タグの間にある "多対多" リレーションシップについても確認します。
製品エンティティをモデル化する
product テーブルの初期モデルには、リレーショナル テーブルのフィールドのみが含まれています。 ただし、e コマース アプリケーションでは、製品ページを表示するときに製品カテゴリ名を表示する必要があります。 また、製品カテゴリ内の製品タグによってクエリも実行します。 これを行うには 2 つの方法があります。製品を製品タグ コンテナーに格納する方法と、タグを製品コンテナーに埋め込む方法です。
製品ごとのタグの数がタグあたりの製品の数よりはるかに少ない場合は、製品テーブルに製品タグを埋め込むことをお勧めします。 各製品とタグの間には "1 対少数" のリレーションシップがあるので、埋め込みに適しています。 また、新しい製品コンテナーには、製品データと共に埋め込まれたタグを格納します。 そのため、新しい製品モデルは次の図のようになります。
パーティション キーを選択する
次に、製品コンテナーのパーティション キーを選択します。 ここでも、パーティション キーを決定するために実行する操作を確認する必要があります。 製品を作成するか、製品を編集することができます。 顧客は、eコマース サイト内を移動するとき、多くの場合、製品カテゴリを使用して移動します。 categoryId
によって製品をフィルター処理してユーザーに表示するクエリが必要です。 クエリをカテゴリ別のすべての製品を含む単一パーティション クエリにするには、categoryId
を製品コンテナーのパーティション キーとして使用します。
そのため、categoryId
は、カテゴリ内のすべての製品を効率的に取得できる適切なパーティション キーです。 タグ ID を埋め込むと、製品とタグの間の多対多リレーションシップで ID を取得できます。 ただし、製品のクエリを実行する場合は、製品データだけでなく、カテゴリ名とタグ名も表示する必要があります。 製品のクエリを実行するときに、各製品のカテゴリ名と製品タグの名前を取得するにはどうすればよいでしょうか。
現在、カテゴリの製品ページを表示するには、次のクエリを実行する必要があります。
- 製品コンテナーのクエリを実行して、カテゴリ内のすべての製品を取得します。
- productCategory コンテナーのクエリを実行して、製品カテゴリの名前を取得します。
- 次に、最初のクエリによって返されたすべての製品について、productTag コンテナーに対する 3 番目のクエリを実行して、各製品タグの名前を取得します。
製品エンティティを非正規化する
前述のすべてのクエリを実行すると、うまくいく可能性があります。 ただし、このアプローチはあまりスケーラブルではありません。 NoSQL データベースでは、コンテナー間の "結合" が存在しないため、結合を選択できないことに注意してください。 また、NoSQL データベースの目的は、できるだけ少ない要求数でアプリケーション データをフェッチできるように、データをモデル化することで要求数を減らすことである点にも注意してください。
そのため、データを "非正規化" することが解決策になります。 非正規化により、データ モデルを最適化し、アプリケーションに必要なすべてのデータをクエリで処理できる状態にすることができます。
この例では、データを非正規化するために、カテゴリの名前やタグ配列の各タグの名前などのプロパティを追加します。 これらのプロパティを追加することで、クライアントに返す必要のあるすべてのデータを 1 回の要求で取得できるようになります。