假设我有以下MessageSchema模型:
var MessageSchema = new Schema({
userId: String,
username: String,
message: String,
date: Date
});
mongoose.model('Message', MessageSchema)
有人可以告诉我以下两种会议模式的实现之间的区别吗?感谢。
var Meetings = new Schema({
_id: ObjectId,
name: String,
messages: [MessageSchema],
...
});
var Meetings2 = new Schema({
_id: ObjectId,
name: String,
messages: [{type: Schema.ObjectId, ref: 'Message'}],
...
});
答案 0 :(得分:1)
会议消息字段包含Message对象数组,而 Meetings2 消息字段包含消息ID的数组。
var Meetings2 = new Schema({
...
messages: [{type: Schema.ObjectId, ref: 'Message'}],
...
});
可以写成
var Meetings2 = new Schema({
...
messages: [Schema.ObjectId],
...
});
ref 只是mongoose中的辅助函数,可以更轻松地populate消息。
总结一下。在Meetings中,您将消息嵌入到数组中,而在Meetings2中,您可以引用消息。
答案 1 :(得分:1)
主要区别在于Meeting
模型嵌入MessageSchema
(非规范化),而Meeting2
模型引用它(规范化)。选择的差异归结为您的模型设计,这主要取决于您查询和更新数据的方式。通常,如果子文档很小并且数据不经常更改,您可能希望使用嵌入式架构设计方法。此外,如果Message
数据少量增长,请考虑对模式进行非规范化。嵌入式方法允许您进行优化读取,因此可以更快,因为您只执行单个查询,因为所有数据都驻留在同一文档中。
另一方面,如果您的Message
文档非常大,请考虑引用,以便将它们保存在您可以引用的单独集合中。确定引用方法的另一个因素是文档是否大量增长。另一个重要的考虑因素是数据变化(波动性)与其阅读方式的频率。如果定期更新,那么引用是一种很好的方法。这种方式可以增强快速写入。
您可以使用嵌入和引用的混合,即使用频繁访问的数据创建一个子文档数组,但需要参考实际文档以获取更多信息。
一般的经验法则是,如果您的应用程序的查询模式是众所周知的,并且数据往往只能以一种方式访问,那么嵌入式方法效果很好。如果您的应用程序以多种方式查询数据,或者您无法预测数据查询模式,则更为规范化的文档引用模型将适用于此类情况。