我应该如何在mongodb / nosql中存储数据?

时间:2013-07-07 14:51:14

标签: node.js mongodb mongoose database nosql

我正在node.js和mongodb(mongoose模块)上编写一个大型社交网络。 这意味着数据库中将有许多用户和大数据。

我已经创建了用户注册,现在我需要允许用户互相写私信。

问题:

1)我应该如何存储有关发送私信的数据? 我想过两种方法:

第一

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字段到Message表,其中只有一个集合m,其中数组存储所有消息。

第二

我在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
});

所有邮件都混合在一个表中。但正如我所理解的,这种方法的缺点是数据库中可能有超过百万条私人消息,这就是发送消息from用户和to用户的速度和性能被发送的原因会很糟糕的。 当第一个方法时,所有消息都在数组中。

那么,我应该选择哪种方式或任何其他想法?

2)我有第一种方法的数组:var arr = [] 问题:我可以在arr中放入多少个对象? arr的大小是多少?例如,如果我推送类似arr.push({t: #, f: #, m: 'message...'})的内容?

1 个答案:

答案 0 :(得分:6)

通常,MongoDB鼓励嵌入数据而不是关系,因为这允许通过单个查询获取所有相关数据。但是有一个例外:MongoDB不喜欢无限增长的文档。

当文档在其生命周期内逐渐增长时,数据库必须经常重新分配硬盘空间。这会减慢写入速度并导致数据库碎片化。此外,文档的硬编码大小限制为16MB(主要是为了阻止文档增长)。用户在其成员资格期间积累越来越多的私人消息将是无限期增长的一个很好的例子。

在您的情况下,确定最常见的用例非常重要。你打算如何向用户展示私人消息?他们会在一个长HTML页面上看到他们用全文获得的所有消息吗?不太可能。

您可能希望将其列为包含发件人和标题的电子邮件收件箱,并在用户点击它们时显示实际内容。在这种情况下,您应该只存储具有此元数据的数组,并将实际内容存储在用户实际单击消息时查询的其他集合中。您仍然可以通过这种方式实现增长,但这不会成为问题,因为用户文档中存储的每条消息的数据要少得多。

您可能只希望在每个正常页面展示中显示未读取的消息,而旧私人消息的完整列表是一个特殊页面,使用频率较低。在这种情况下,您只会将未读消息嵌入到用户文档中,并在读取后将其移动到另一个集合中。这可以防止文档增长,因为大多数用户会将未读消息列表保持在低位。