1. ホーム
  2. nosql

[解決済み] NoSQLでレコードのリレーションを追跡するには?

2022-06-16 17:52:53

質問

私は、NoSQL KVP または Document データベースにおける外部キーおよびインデックスに相当するものを理解しようとしています。ピボット テーブル (2 つのオブジェクト間の関係を示すキーを追加する) がないため、通常の Web ページに役立つ方法でデータを取得できる方法について、私は本当に困っています。

あるユーザーがいて、そのユーザーがサイト上に多くのコメントを残したとします。そのユーザーのコメントを追跡するために私が思いつく唯一の方法は、次のとおりです。

  1. ユーザーオブジェクトにそれらを埋め込む (これはかなり無駄のように思えます)
  2. を作成し、維持します。 user_id:comments 値を作成し、必要に応じてそれらを取得できるように、各コメントのキーのリスト [comment:34, comment:197, etc...] を格納するようにします。

しかし、2 番目の例では、quot;active_comments" というキーのような他のものを追跡するために使用すると、すぐにレンガの壁にぶつかることになります。 を大量に消費することになります。 というキーがありますが、これには 3,000 万件の ID が含まれているため、最近のアクティブなコメントを知るために各ページにクエリを発行するには 膨大なコストがかかります。また、次のようなことが起こりがちです。 レース条件 が発生しやすくなります。

NoSQLデータベースで次のような関係を追跡するにはどうしたらよいでしょうか?

  • ユーザーのすべてのコメント
  • すべてのアクティブなコメント
  • キーワード]がタグ付けされたすべての投稿
  • あるクラブに所属する全学生 - またはある学生が所属する全クラブ

それとも、私の考え方が間違っているのでしょうか?

どのように解決するのですか?

NoSQL の方法で多対多の関連付けを保存する方法に関するすべての回答は、同じものに帰結します。 データを冗長に保存することです。

NoSQLでは、データエンティティ間の関係に基づいてデータベースを設計するのではありません。 データベースに対して実行するクエリに基づいてデータベースを設計するのです。 リレーショナル データベースを非正規化するときに使用するのと同じ基準を使用します。もしデータがまとまりを持つことがより重要であれば (正規化されたテーブルではなく、カンマ区切りのリストの値を考えてください)、そのようにします。

しかし、これは必然的に他のタイプのクエリ (任意のユーザーによる任意の記事のコメント) を犠牲にして、1つのタイプのクエリ (たとえば、任意の記事に対する任意のユーザーによるコメント) のために最適化します。 もし、アプリケーションが両方のタイプのクエリを同じように最適化する必要がある場合は、非正規化を行うべきではありません。 同様に、リレーショナルな方法でデータを使用する必要がある場合は、NoSQL ソリューションを使用するべきではありません。

非正規化と冗長化には、冗長なデータセットが互いに同期しなくなるリスクがあります。 これは アノマリー . 正規化されたリレーショナルデータベースを使用する場合、RDBMSは異常を防止することができます。 非正規化されたデータベースやNoSQLでは、異常を防ぐためのアプリケーションコードを書くことが責任となります。

NoSQLデータベースが異常を防ぐという大変な仕事を代行してくれるのは素晴らしいことだと思うかもしれません。 これを実現できるパラダイムがあります--リレーショナルパラダイムです。