首先,我认为您提出了正确的问题。您是对的,作为一个非关系型数据库,MongoDB 不会为您管理参照完整性问题。如果确实存在引用完整性问题,这可能会让人有些头疼,因为如果您的某个用户修改了您的一条信息,您会发现自己处于可能需要更新大量文档的情况'已存储在您的所有文档中。让我们以你的例子为例,除了翻译成我通常期望的第一次尝试如何在 MongoDB 上设置它......
db.posts.save({
author:"susan@yahoo.com",
name:"Susan Person",
text:"This is my first post. Isn't it fancy?",
comments:[
{ author:"john@google.com", name:"John", text:"What a great post!" },
{ author:"sally@email.com", name:"Sally", text:"You really put some thought into this." }
]
});
db.authors.save({
_id:"susan@yahoo.com",
name:"Susan Person",
favorite_icecream:"Chocolate",
});
我比你的例子更充实了一些东西,但我希望这能帮助你明白我要说什么。
所以。在没有听起来过于禅宗的情况下,我认为回答您问题的唯一方法是问另一个问题:您真的需要用新昵称更新所有现有评论吗?
根据我的经验,答案可能是否定的。但是,如果帖子的原作者(在这种情况下是苏珊)更改了他们的用户名,您可能想要这样做。那么你是怎么做到的呢?您首先修改作者文档,然后选择所有带有 { author:"susan@yahoo.com" } 的文档并更新这些帖子的作者。
使用您的经验和您对系统将如何使用的知识来决定您的架构。如果您确实需要确保评论的名称反映作者集合中的条目,那么您还必须为所有这些条目做额外的工作。
您的问题还有一些更高级的解决方案。例如,您可能决定需要快速访问帖子的前 10 条评论,然后您可以让用户等待,同时将其余评论从数据库中异步拉出并进行相关匹配将数据拉到一起。在这种情况下,您的架构看起来与上述类似,但您不会存储超过 10 条评论,并将名称复制到帖子上,您可能会将所有剩余评论存储在仅引用用户的附加集合中电子邮件。然后,当您去查找评论时,您可以对用户集合中的电子邮件进行第二次查询,并确保您获得最新的名称。随着时间的推移,评论会滚动,
有关您可能想要选择的不同选项的更详细比较,请参阅以下链接:
http://www.alvinonmongodb.com/2012/07/schema-design-3-embedding-versus.html
正如文章作者所说:
问题并不是真正的嵌入或链接,而应该是“我的用例和访问模式是什么”。如果你知道这一点,那么嵌入、链接或混合模型的决定就更容易做出了。