【问题标题】:Document Databases: Redundant data, references, etc. (MongoDB specifically)文档数据库:冗余数据、参考资料等(特别是 MongoDB)
【发布时间】:2011-04-26 18:51:03
【问题描述】:

似乎我遇到了很多情况,其中构建数据的适当方法是将其拆分为两个文档。假设它是针对连锁店的,您正在保存每个客户访问过的商店。商店和客户需要是独立的数据片段,因为它们与许多其他事物交互,但我们确实需要将它们关联起来。

因此,简单的答案是将用户的 Id 存储在商店文档中,或者将商店的 Id 存储在用户的文档中。通常,您希望访问 1-2 条其他数据用于显示目的,因为 Id 没有用。可能是客户名称或商店名称。

  1. 您通常存储整个文档的副本吗?还是只存储您需要的数据?可能取决于文档的大小以及您需要多少。
  2. 您如何处理存在重复数据的事实?当数据发生变化时,你会去寻找数据吗?加载时每隔一段时间更新数据?仅在您负担得起陈旧数据时才复制?

非常感谢您的意见和/或任何“最佳实践”的链接或至少对这些主题进行合理讨论的链接。

【问题讨论】:

    标签: mongodb document-database


    【解决方案1】:

    基本上有两种情况:freshstale

    新鲜数据

    存储重复数据很容易。维护重复数据是困难的部分。因此,最简单的做法是避免维护,一开始就不要存储任何重复的数据。如果您需要新鲜数据,这主要是有用的。仅存储引用,并在需要检索信息时查询集合。

    在这种情况下,由于额外的查询,您会有一些开销。另一种方法是跟踪重复数据的所有位置,并在每次更新时更新所有实例。这也涉及开销,尤其是在您提到的 N 对 M 关系中。因此,无论哪种方式,如果您需要新数据,您有一些开销。你不能两全其美。

    过时的数据

    如果您有能力拥有过时的数据,事情就会变得容易得多。为避免查询开销,您可以存储重复数据。为避免必须维护重复数据,您不会存储重复数据。至少不会主动

    在这种情况下,您还希望只存储文档之间的引用。然后使用周期性的 map-reduce 作业来生成重复数据。然后,您可以查询单个 map-reduce 结果,而不是单独的集合。这样可以避免查询开销,但也不必追踪数据更改。

    总结

    仅存储对其他文档的引用。如果您负担得起陈旧的数据,请使用定期 map-reduce 作业来生成重复数据。避免维护重复数据;它复杂且容易出错。

    【讨论】:

    • 好的,总的来说这对我来说是有意义的。我唯一不完全清楚的是您描述的 map-reduce 结果情况,它似乎假设所有数据都需要相同的新鲜度。在此处的示例中,用户数据必须是新鲜的,但用户的商店名称数据可能是陈旧的。所以我不想从周期性的 map-reduce 中读取用户数据和存储数据,因为用户数据不会过时。那是否会迫使我完全进入“新鲜”场景?
    • @Jim:如果部分数据,在这种情况下访问的商店名称,可能是陈旧的,您可以使用Gates VP's solution。请记住在商店中更新商店名称时也要更新客户文档。
    • @NielsvanderRest 你能解释更多关于地图减少的信息吗?
    • 我不熟悉“陈旧”和“新鲜”数据术语。这些术语是什么意思?
    【解决方案2】:

    这里的答案实际上取决于您需要数据的最新程度。

    @Niels 在这里有一个很好的总结,但我认为你可以“作弊”是公平的。

    假设您要显示用户使用的商店。这里明显的问题是您不能将商店“嵌入”到用户 b/c 中,因为商店本身就太重要了。但是你可以做的是在用户中嵌入一些存储数据。

    只需使用您想要显示的内容,例如“商店名称”。所以你的用户对象看起来像这样:

    {
      _id : MongoID(),
      name : "Testy Tester",
      stores : [ 
                 { _id : MongoID(), "name" : 'Safeway' },
                 { _id : MongoID(), "name" : 'Walmart' },
                 { _id : MongoID(), "name" : 'Best Buy' }
                ]
    }
    

    这样您可以显示典型的“网格”视图,但需要一个链接来获取有关商店的更多数据。

    【讨论】:

    • +1 当数据是定期从现有数据中生成时,这是一种很好的方法。如果您手动插入额外的数据,您也必须手动更新它。当然,对于商店名称等不太可能改变的事物,这不是问题。
    【解决方案3】:

    回答您的直接问题:

    1. 没有重复。
    2. 没有重复。

    ;)

    您应该拥有的唯一重复值是“简单”值,例如权重(可能恰好相同,但在单独存储的时间或空间上都没有效率),以及引用另一个对象的 ids(是重复值,但比它们替换的重复对象数据更小且更易于管理)。

    现在,回答您的情况:您想要的是多对多关系。这里通常的解决方案是创建第三个“直通”或“桥接”表/集合,可能称为 StoreUsers:

    StoreUsers
    ----------
    storeuser_id
    store_id
    user_id
    

    您为商店和用户之间的每个链接添加一条记录,无论是针对不同的商店、不同的用户还是一个商店中的一组用户。然后,您可以为商店或用户独立查找此内容。 MongoDB 也提倡这种方法。它不是特定于 RDBMS 的。

    【讨论】:

    • 等一下!那么这和RDBMS有什么区别呢?
    • 与 Mongo 一起做一个大项目,如果它被认为是正确的方法,我发现这个答案非常令人失望。一旦您使用引用,Mongo 就比任何关系数据库都要慢得多。我试图通过检查复制数据的最佳方式来解决这个问题,我所看到的只是人们告诉我要像在关系数据库中那样做……那么为什么要使用 MongoDB 呢?
    猜你喜欢
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多