0

私はmysqlの知識を持っていますが、mongodbを学習/理解しようとしています。これまでに遭遇した問題は、非リレーショナルデータベースのアイデアです。参加はありません、そしてこれはちょっとバグです(しかし私は理由を理解しています)。私に答えてほしいのは、次の問題の解決策です。

投稿とコメントがあるとしましょう。mongodbで2つのオブジェクトを作成し、特定の投稿に特定のユーザーによるコメントを表示する場合は、それぞれにクエリを実行してから、IDでテーブルを結合します。私が理解していないのは、いくつかの投稿にすでにコメントしているユーザーがニックネームを変更した場合にどうなるかということです。次に、それをどのように修正しますか。ユーザーがこれまでにコメントしたすべての投稿とコメントを変更する必要がありますか?

dbスキーマ:

POSTS
    text
    id

COMMENT
    text
    post_id
    author_name
4

3 に答える 3

3

まず第一に、あなたは正しい質問をしていると思います。その通り、非リレーショナル データベースとして、MongoDB は参照整合性に関する問題を管理しません。参照整合性に本当に問題がある場合、これは少し頭痛の種になる可能性があります。なぜなら、ユーザーの 1 人が、あなたが管理している情報の一部を変更した場合に、更新する必要のあるドキュメントがたくさんあるという状況に陥る可能性があるからです。すべてのドキュメントに保存されています。MongoDBでのセットアップ方法の最初の試みとして、私が通常期待するものに翻訳することを除いて、あなたの例を見てみましょう...

db.posts.save({
    author:"susan@yahoo.com",
    name:"Susan Person",
    text:"This is my first post. Isn't it fancy?",
    comments:[
         { author:"john@google.com", name:"John", text:"What a great post!" },
         { author:"sally@email.com", name:"Sally", text:"You really put some thought into this." }
    ]
});

db.authors.save({
    _id:"susan@yahoo.com",
    name:"Susan Person",
    favorite_icecream:"Chocolate",
});

私はあなたの例よりも少し肉付けしましたが、これが私が言おうとしていることを理解するのに役立つことを願っています.

そう。過度に禅に聞こえることはありませんが、あなたの質問に答える唯一の方法は、別の質問をすることだと思います。既存のすべてのコメントを新しいニックネームで本当に更新する必要がありますか?

私の経験では、答えはおそらくノーです。ただし、投稿の元の作成者 (この場合はスーザン) がユーザー名を変更した場合は、変更したい場合があります。では、どうやってそれを行うのですか?最初に作成者のドキュメントを変更し、次に { author:"susan@yahoo.com" } を含むすべてのドキュメントを選択して、それらの投稿の作成者を更新します。

スキーマを決定するために、システムがどのように使用されるかについての経験と知識を使用してください。コメントの名前が作成者コレクションのエントリを反映していることを本当に確認する必要がある場合は、それらすべてに対して追加の作業を行う必要があります。

あなたの質問に対するより高度な解決策もいくつかあります。たとえば、投稿の最初の 10 個のコメントにすばやくアクセスする必要があると判断した場合、その後、データベースから残りのコメントを非同期に引き出して関連する一致を実行する間、ユーザーを待たせる余裕があります。データをまとめます。その場合、スキーマは上記のようになりますが、投稿に名前がコピーされたコメントを 10 個以上保存することはなく、残りのすべてのコメントを、ユーザーのみを参照する追加のコレクションに保存することもできます。 Eメール。次に、コメントを検索するときに、users コレクション内の電子メールに対して 2 番目のクエリを実行して、最新の名前を取得していることを確認できます。時間が経つにつれて、コメントはスクロールし、

選択できるさまざまなオプションのより詳細な比較については、次のリンクを参照してください。

http://www.alvinonmongodb.com/2012/07/schema-design-3-embedding-versus.html

記事の著者は次のように述べています。

問題は実際には埋め込みやリンクではなく、「私のユースケースとアクセスパターンは何ですか」であるべきです。それがわかっている場合は、埋め込み、リンク、またはハイブリッド モデルの決定がより簡単になります。

于 2012-11-27T13:10:50.577 に答える
2

あなたが望むものを達成するためのさまざまな方法があります:

  • name の代わりに _id を使用します。これは SQL の外部キーとほぼ同じですが、関連するオブジェクトが存在するかどうかなどのチェックはありません。もちろん、ユーザー名を表示したい場合は、ユーザー名ごとにクエリを実行する必要があります。これを使用するとオーバーヘッドが発生しますが、MongoDB の負荷が高くない場合は、それほど大きな問題にはなりません。さらに良いことに、取得したユーザーの数に応じて、id とユーザー名にインデックスを作成して、ユーザー名を RAM に保持することができます。つまり、読み取りが非常に高速になります。

  • すべてのコメントを更新 : 名前を変更した後、特定のユーザー名のすべてのコメントを更新できます。これを機能させるには、コメント コレクション内のユーザー名の横に user_id を保存し、id をクエリしてユーザー名を変更します。MongoDB には、これを高速に実行する方法があると思います。

  • 埋め込みコレクションを使用する: MongoDB には埋め込みコレクションがあり、これらの問題のいくつかを解決し、別の問題を作成します。コメント内にユーザーを埋め込みたくはありませんが、他のユース ケースでは非常に便利です。ここで言及しているだけです。

MongoDB の操作

全体的な問題は、NoSQL データベースを使用する場合、ユース ケースについて考えなければならないことです。「データを正規化し、クエリの書き方を確認する」ということではなく、「データをこのように使用したい、データをどのように保存する必要があるか」ということです。したがって、上記から、より便利な他のソリューションがあるかもしれません。

たぶん、ユーザー名の前に特別な ID を使用し (ID は何でもかまいません)、アプリケーションを使用してユーザー名を抽出します。あるいは、コメントとユーザー情報が独自のコレクションの横に一緒に保存され、何かが変更された場合に再生成される、ある種のマージされたドキュメントの複製されたコレクションを保持しているのかもしれません。

この作業方法に慣れるまでには時間がかかりますが、すぐに慣れます。始めたばかりの場合、おそらく 1 秒あたり 100000 ヒットのプラットフォームを開発していないので、オブジェクト ID を保存し、その ID に対して 2 番目のクエリを実行して、必要に応じてユーザー名を取得できます。

于 2012-11-27T12:12:21.043 に答える
0

たとえそれが優れたスキーマではないリレーショナルデータベースであったとしても。コメントドキュメントでは、author_nameの代わりにauthor_idを使用します。このIDは、そのユーザーに対して一意です。次に、author_nameとauthor_idを関連付ける単一のユーザードキュメントを作成します。

これで、作成者を変更すると、1つのドキュメントでのみ発生します。

于 2012-11-27T12:00:59.973 に答える