3

node.js と mongodb (mongoose モジュール) で大規模なソーシャル ネットワークを作成しています。つまり、データベースには多くのユーザーと大規模なデータが存在します。

ユーザー登録を作成しましたが、ユーザーが互いにプライベート メッセージを書き込めるようにする必要があります。

質問:

1) プライベート メッセージの送信に関するデータをどのように保存すればよいですか? 私は2つの方法を考えました:

最初

var schemaUser = new mongoose.Schema({
    i: Number,
    ...
    message: { type: Schema.ObjectId, ref: 'Message' }
});
var schemaMessage = new mongoose.Schema({
    m: [{
        f: Number, // value i from schemaUser, means from user
        m: String, // message
        d: { type: Date, default: Date.now } // date
    }]
});
module.exports = {
    User: db.model('User', schemaUser),
    Message: db.model('Message', schemaMessage)
}

このようにして、すべてのユーザーがテーブルへのmessageフィールドを持ち、コレクションが 1 つだけあり、配列にすべてのメッセージが格納されます。Messagem

2番目

次のようにすべてのメッセージに保存しMessagesます。

var schemaMessage = new mongoose.Schema({
    t: Number, // means to what user this messages sent
    f: Number, // value i from schemaUser, means from what user message sent
    m: String, // message
    d: { type: Date, default: Date.now } // date
});

すべてのメッセージが 1 つのテーブルに混在しています。しかし、私が理解したように、この方法の欠点は、データベースに100万を超えるプライベートメッセージが存在する可能性があることです。そのため、fromユーザーとtoユーザーが送信したメッセージを見つける速度とパフォーマンスが低下します. 最初のメソッドでは、すべてのメッセージが配列にあります。

それで、私はどちらの方法を選ぶべきですか、それとも他のアイデアはありますか?

2)最初の方法のような配列があります:var arr = [] 質問:いくつのオブジェクトを入れることができarrますか?の大きさはarr?たとえば、次のようなものをプッシュするとarr.push({t: #, f: #, m: 'message...'})?

4

1 に答える 1

7

一般に、MongoDB はリレーションではなくデータの埋め込みを推奨しています。これにより、関連するすべてのデータを 1 回のクエリで取得できるからです。ただし、例外があります。MongoDB は、無限に大きくなるドキュメントを好みません。

ドキュメントが存続期間中に徐々に大きくなると、データベースは頻繁にハード ドライブ領域を再割り当てする必要があります。これにより、書き込みが遅くなり、データベースの断片化が発生します。また、ドキュメントにはハードコーディングされた 16MB のサイズ制限があります (主にドキュメントの増大を抑えるため)。メンバーシップ中に個人的なメッセージをどんどん蓄積するユーザーは、無限の成長の良い例です。

あなたの状況では、最も頻繁に使用するユースケースを特定することが重要です。プライベート メッセージをユーザーにどのように表示しますか? これまでに受け取ったすべてのメッセージを 1 つの長い HTML ページで全文表示できるでしょうか? ありそうもない。

送信者と見出しを含む電子メールの受信箱のようにそれらをリストし、ユーザーがそれらをクリックしたときに実際のコンテンツを表示したいと思うでしょう。その場合は、このメタデータを含む配列を保存し、ユーザーが実際にメッセージをクリックしたときにクエリされる別のコレクションに実際のコンテンツを保存する必要があります。この方法でも成長はありますが、ユーザー ドキュメントに保存されるメッセージごとのデータがはるかに少ないため、それほど問題にはなりません。

また、通常のページ インプレッションごとに未読のメッセージのみを表示したい場合もありますが、古いプライベート メッセージの完全なリストはあまり使用されない特別なページです。その場合は、未読メッセージのみをユーザー ドキュメントに埋め込み、既読後に別のコレクションに移動します。これにより、ほとんどのユーザーは未読メッセージのリストを低く保つため、ドキュメントの増大を防ぐことができます。

于 2013-07-08T14:10:12.273 に答える