我有mysql的知识,但我正在努力学习/理解mongodb,到目前为止我遇到的问题是非关系型数据库的想法。没有join,这有点why(不过我理解为什么)。我希望你回答我的是以下问题的解决方案:
假设我们有帖子和评论。我们在mongodb中创建了两个对象,如果我们想要显示某个用户对某个帖子的评论,我们只需查询每个对象,然后按id组合表。我不明白的是,如果已经评论了几个帖子的用户更改了他的昵称,会发生什么。那么我们该如何解决这个问题呢。我必须更改用户曾经评论过的所有帖子和评论吗?
数据库架构:
POSTS
text
id
COMMENT
text
post_id
author_name发布于 2012-11-27 21:10:51
首先,我认为你问的问题是对的。您说得对,作为一个非关系型数据库,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",
});我比你的例子更充实了一些东西,但我希望这能帮助你理解我将要说的话。
所以。在不显得过于禅宗的情况下,我认为回答你的问题的唯一方法是问另一个问题:你真的需要用新的昵称更新所有现有的评论吗?
根据我的经验,答案可能是否定的。但是,如果帖子的原始作者(在本例中是苏珊)更改了他们的用户名,您可能会想要这样做。那么如何做到这一点呢?首先修改authors文档,然后选择带有{ author:"susan@yahoo.com“}的所有文档,并在这些帖子上更新作者。
使用您的经验和您对如何使用系统的知识来决定您的模式。如果您确实需要确保评论的名称反映authors集合中的条目,那么您还必须为所有这些条目做额外的跑腿工作。
对于您的问题,还有一些更高级的解决方案。例如,您可能决定需要快速访问帖子上的前10条评论,在此之后,您可以让用户等待,而您可以异步地将其余评论从数据库中拉出,并进行相关匹配以将数据组合在一起。在这种情况下,您的模式将类似于上面,但是您不会存储超过10条带有复制到帖子上的名称的评论,并且可以将所有剩余的评论存储在一个额外的集合中,该集合仅引用用户的电子邮件。然后,当您查找评论时,您可以对users集合中的电子邮件进行第二次查询,并确保您获得的是最新的名称。随着时间的推移,评论会滚动,除非一篇帖子已经过时,永远不会收到任何额外的评论(我认为这意味着没有人关心他们的名字是否被更新),否则它最终会实现与数据库其余部分的引用完整性。
有关您可能要选择的不同选项的更详细比较,请参阅以下链接:
http://www.alvinonmongodb.com/2012/07/schema-design-3-embedding-versus.html
正如这篇文章的作者所说:
问题不是真正的嵌入或链接,而是“我的用例和访问模式是什么”。如果你知道这一点,那么决定是嵌入、链接还是混合模型就更容易了。
发布于 2012-11-27 20:12:21
有不同的方法可以达到你想要的效果:
使用MongoDB
总体问题是,当使用NoSQL数据库时,您必须考虑您的用例。这不是“我们标准化我们的数据,然后看看我们如何编写我们的查询”,而是“我们想以这种方式使用数据,我们需要如何存储数据”。因此,从上面来看,可能还有其他更方便的解决方案。
可能是在用户名前面使用了一个特殊的id (记住,id可以是任何东西),然后使用应用程序提取用户名。或者,它保留了某种类型的合并文档的重复集合,其中注释和用户信息一起存储在各自的集合旁边,这些集合可以在发生变化时重新生成。
习惯这种工作方式需要一些时间,但你会习惯的。如果你刚刚开始,你可能不是在开发每秒100000次点击的平台,所以你可以只存储对象id,并在需要时对该id进行第二次查询,以获得用户名。
发布于 2012-11-27 20:01:00
即使它是一个关系数据库,这也不是一个很好的模式。您应该在注释文档上使用author_id,而不是author_name。该id对于该用户来说是唯一的。然后创建一个将author_name和author_id关联起来的单用户文档。
现在,当你改变作者的时候,它只发生在一个文档中。
https://stackoverflow.com/questions/13583746
复制相似问题