【问题标题】:How to deal with relationships while using mongodb使用mongodb时如何处理关系
【发布时间】:2012-03-19 08:41:18
【问题描述】:

我知道,以“非规范化方式”或“nosql 方式”思考。

但请告诉我这个简单的用例。

db.users
db.comments

一些用户发表评论,我想在获取评论时获取一些用户数据。 假设我想显示动态数据,例如“用户级别”,以及静态数据,例如“用户名”。

静态数据我永远不会有问题,但动态数据呢?

用户级别在用户整理中,我需要将非规范化数据复制到 cmets 以实现读取性能,同时还要更新用户级别。

这是否可以以某种方式存档?

【问题讨论】:

    标签: mongodb join relationships denormalized


    【解决方案1】:

    编辑:

    刚刚找到来自 10gen 的 Brendan McAdams 的 an answer,他显​​然比我更有权威,他建议嵌入文档。


    旧文本:

    第一个是手动在每个评论中包含他们所属用户的 ObjectID。

    comment: { text : "...", 
               date: "...", 
               user: ObjectId("4b866f08234ae01d21d89604"),
               votes: 7 }
    

    第二种,聪明的方法是use DBRefs

    我们向磁盘添加了额外的 I/O,这会降低性能,对吗? (我不确定这在内部是如何工作的)因此我们需要尽可能避免链接,对吧?

    是的 - 还会有一个查询,但驱动程序会为您完成 - 您可以将其视为一种语法糖。会影响性能吗?实际上,这也取决于 :) Mongo 如此快速的原因之一是它使用 memory mapped files 并且 mongo 尽量将所有工作集(加上索引)直接保存在 RAM 中。每 60 秒(默认情况下)它会将 RAM 快照与基于磁盘的文件同步。
    当我说 working set 时,我的意思是您正在使用的东西:您可以拥有三个集合 - foobar baz,但是如果你现在只使用 foo 和 bar,它们应该被加载到 ram 中,而 baz 留在磁盘上被遗弃。此外,内存映射文件只允许加载集合的一部分。因此,如果您正在构建诸如 engadget 或 techcrunch 之类的东西,那么过去几天工作集很可能是 cmets,并且旧页面的恢复频率会降低(cmets 会按需生成到内存中),所以它不会不会显着影响性能。

    所以回顾一下:只要你在内存中保持工作集(你可能认为这是读/写缓存),获取这些东西是超快的,再查询一次就不会成为问题。如果您使用不适合内存的数据切片,则速度会degradation,但我现在不知道您的情况-这是可以接受的,因此在这两种情况下我都倾向于选择请使用链接。

    【讨论】:

    • hmm,所以使用 DBRefs 可以确保自动进程链接,而无需在客户端进行额外的查询,对吗?
    • @zebnat 好吧,这取决于 - 例如C++ 驱动程序无法处理它们,因此您必须手动完成所有工作,但许多驱动程序可以做到这一点:在 Ruby 中,您调用解引用方法,Python 可以做到这一点automagically
    • 作为一个澄清 - 从技术上讲,还会有一个查询,但它隐含地隐藏在引擎盖下
    • 当我们在后台谈论“另一个查询”时,我们向磁盘添加了额外的 I/O,这会降低性能,对吗? (我不确定这是如何在内部工作的)因此我们需要尽可能避免链接,对吧? - 但我暗示太多了 - 但也许如果他们通过 mysql 中的触发器之类的东西更新“链接”或嵌入数据并且数据保持在那里重复/自动更新,读取查询会快得多。
    猜你喜欢
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多