Node.js MongoDB性能$ref vs嵌入式

Node.js MongoDB性能$ref vs嵌入式,node.js,performance,mongodb,reference,Node.js,Performance,Mongodb,Reference,我最近启动了一个使用mongodb和nodejs构建restful web服务的项目。不幸的是,mongodb对我来说非常陌生,来自关系数据库世界的我问了自己很多问题 让我向你解释我的问题: 其目标是构建一种具有社交功能的内容管理系统,比如用户可以发布可以共享和评论的主题。 我有两种可能做到这一点:一种是使用引用获取用户发布的主题,另一种是使用主题作为用户的嵌入文档而不是引用 所以基本上我可以有以下两种模式: var UserSchema=新模式({ 用户名:{ 类型:字符串, 独一无二:没错

我最近启动了一个使用mongodb和nodejs构建restful web服务的项目。不幸的是,mongodb对我来说非常陌生,来自关系数据库世界的我问了自己很多问题

让我向你解释我的问题: 其目标是构建一种具有社交功能的内容管理系统,比如用户可以发布可以共享和评论的主题。 我有两种可能做到这一点:一种是使用引用获取用户发布的主题,另一种是使用主题作为用户的嵌入文档而不是引用

所以基本上我可以有以下两种模式:

var UserSchema=新模式({
用户名:{
类型:字符串,
独一无二:没错,
必填项:true
},
密码:{
类型:字符串,
必填项:true
},
姓名:{
类型:字符串
},
名字:String,
电话:String,
topics:[Topic.schema]
});
var TopicSchema=新模式({
_创建者:{
类型:字符串,
参考:“用户”
},
描述:字符串,
注释:[comments.schema],
与以下人员共享:[{
类型:Schema.ObjectId,
参考:“用户”
}]//[{type:String,ref:'User'}]
});
var CommentSchema=新模式({
_创建者:{
类型:字符串,
要求:正确
},
正文:{
类型:字符串,
必填项:true
},
});更好的解决方案:使用引用获取用户发布的主题

对于这个数据库的使用,通常需要考虑MMAPv1文档大小限制(16MB)。将用户、主题和注释放在一个文档中可以使文档不受约束地增长。如果每个主题都是一页文本(1K),那么在达到限制之前,每个用户可能有大约16000个主题。这似乎很大,但如果你决定在产品成熟时将图像、视频、声音放在主题中,会发生什么?以后从嵌入式模式转换为规范化模式将比今天简单的设计选择要困难得多

类似地,如果注释可能增长到导致主题超过16MB限制,则它们应该位于单独的集合中。不大可能发生的可能但是如果你写的东西会成为,比如说,他们的热门文章的评论

以下是mongo关于更好的解决方案的建议:使用引用获取用户发布的主题

对于这个数据库的使用,通常需要考虑MMAPv1文档大小限制(16MB)。将用户、主题和注释放在一个文档中可以使文档不受约束地增长。如果每个主题都是一页文本(1K),那么在达到限制之前,每个用户可能有大约16000个主题。这似乎很大,但如果你决定在产品成熟时将图像、视频、声音放在主题中,会发生什么?以后从嵌入式模式转换为规范化模式将比今天简单的设计选择要困难得多

类似地,如果注释可能增长到导致主题超过16MB限制,则它们应该位于单独的集合中。不大可能发生的可能但是如果你写的东西会成为,比如说,他们的热门文章的评论


以下是mongo关于

嗨,Steve的建议,谢谢你的回答。事实上,我们正处于项目的最开始阶段,我还在设计数据库,所以不用担心转换数十亿的数据:)我们计划使用AmazonS3来处理文件,而不是将所有内容都存储在数据库中,因此,对于这件事,我们已经完成了。例如,如果我使用规范化模式,我应该发出2个请求来检索一个主题+一些用户信息(名称、排名等),还是应该在主题中复制一些用户信息?感谢使用两个find(),一个用于用户集合,一个用于主题集合。为什么?仔细想想,如果每个主题中都有相同信息的副本,您将如何更新用户信息。有了适当的索引,两个获取用户和主题的调用应该是真的,我没有考虑更新信息…,我将研究mongo索引,因为我现在从未使用过它。谢谢你的建议。所有生产mongo查询都应该有索引覆盖。嗨,Steve,谢谢你的回答。事实上,我们正处于项目的最开始阶段,我还在设计数据库,所以不用担心转换数十亿的数据:)我们计划使用AmazonS3来处理文件,而不是将所有内容都存储在数据库中,因此,对于这件事,我们已经完成了。例如,如果我使用规范化模式,我应该发出2个请求来检索一个主题+一些用户信息(名称、排名等),还是应该在主题中复制一些用户信息?感谢使用两个find(),一个用于用户集合,一个用于主题集合。为什么?仔细想想,如果每个主题中都有相同信息的副本,您将如何更新用户信息。有了适当的索引,两个获取用户和主题的调用应该是真的,我没有考虑更新信息…,我将研究mongo索引,因为我现在从未使用过它。谢谢你的建议。所有生产mongo查询都应该有索引覆盖范围。