您好我想构建具有最高性能的mongoDB架构。
一般来说,我的问题是:
更好的是: 内部有大型子文档数组(约10000个)或带引号的2个独立集合(其中一个可能包含50000000条记录)?
详细信息
我有一个带有复杂子文档的mongoDB模型。
var usersSchema = new Schema({
email:{
type: String,
unique: true,
required: true
},
packages : [{
package : {type: Schema.Types.ObjectId, ref: 'Packages'},
from : {type : Schema.Types.ObjectId, ref :'Languages'},
to : {type : Schema.Types.ObjectId, ref :'Languages'},
words : [{
word: {type: String},
progress: {type: Number,default : 0}
}]
}]
});
每个用户可能拥有3-10个包含1000个单词的包。 应用程序可能会有> 10000个用户。 所以我可能会存储大约5千万字。 但我喜欢拥有分页,普通搜索和另一个多汁的mongoDB功能来收集单词。但据我所知,将这些功能与子文档一起使用非常困难。
我的问题是:对于具有无效分页,搜索和更新的系统性能SubDocuments,除了用户或还有一个具有50 000 000条记录的独立模型会更好? 像这样的东西
var wordsSchema = new Schema({
word: {type: String},
progress: {type: Number,default : 0},
user : {type : Schema.Types.ObjectId, ref :'Users'}
}]
});
答案 0 :(得分:2)
什么是更好:内部有大型子文档数组(大约10000个)或带引号的2个独立集合(其中一个可能包含50000000条记录)?
这里首先想到的是:为什么存储一个引用的成本是你在子文档中存储成本的5000倍?
好的,看看你的架构,我认为最好的方法是单词收集,而不是包。
我看到的第一个红旗是你的双重嵌套:
packages : [{
package : {type: Schema.Types.ObjectId, ref: 'Packages'},
from : {type : Schema.Types.ObjectId, ref :'Languages'},
to : {type : Schema.Types.ObjectId, ref :'Languages'},
words : [{
word: {type: String},
progress: {type: Number,default : 0}
}]
}]
在当前版本的MongoDB中,words
子文档将非常难以使用,通常2-3级深度开始出现问题,尤其是位置运算符。
现在考虑到你应该始终以尽可能高的价值工作:
每个用户可能拥有3-10个包含1000个单词的包。
您还要考虑住这份文件的费用。您需要的运算符将是内存中的运算符,例如$pull
,$push
,$addToSet
等,这意味着您需要将整个文档序列化并加载到MongoDB的本机C ++中结构。根据这些文档的流量,这将是一项极其耗费的任务。
考虑您的评论:
它只是在主要用户文档中嵌入单词的棺材中添加了另一个钉子。考虑到我在前一段中所说的内容,这对于在我想用word集合进行大量的读写操作,更不用说用户集合的操作了。
words
数组上使用内存运算符的成本效果不佳。
但我喜欢拥有分页,普通搜索以及另一个多汁的mongoDB功能来收集单词。
如果单词被拆分,这将更好地工作,$slice
也是一个内存中的运算符,可能会在这里遭受性能下降。
这是一个快速合理的回应。我相信还有更多我可以解释我的理由,但这应该足够了。
答案 1 :(得分:1)
根据我的观点,分隔的集合更好
记住一切事情
希望它会有所帮助