文档数据库:冗余数据、参考资料等(特别是MongoDB)

文档数据库:冗余数据、参考资料等(特别是MongoDB),mongodb,document-database,Mongodb,Document Database,我似乎遇到过很多情况,构建数据的适当方法是将数据拆分为两个文档。假设这是针对连锁店的,您正在保存每个客户访问过的商店。商店和客户需要成为独立的数据块,因为它们与许多其他事物交互,但我们确实需要将它们联系起来 因此,简单的答案是将用户Id存储在store文档中,或者将store的Id存储在用户文档中。但通常情况下,您希望访问1-2条其他数据以进行显示,因为Id没有用处。比如顾客的名字,或者商店的名字 您通常会存储整个文档的副本吗?还是只存储所需的数据片段?可能取决于文档的大小和您需要的文档数量 您

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

因此,简单的答案是将用户Id存储在store文档中,或者将store的Id存储在用户文档中。但通常情况下,您希望访问1-2条其他数据以进行显示,因为Id没有用处。比如顾客的名字,或者商店的名字

  • 您通常会存储整个文档的副本吗?还是只存储所需的数据片段?可能取决于文档的大小和您需要的文档数量
  • 您如何处理数据重复这一事实?当数据发生变化时,你会去寻找它吗?在加载数据时,是否每隔一段时间更新数据?只有在您负担得起过时数据时才复制

  • 如果您能提供任何类型的“最佳实践”或至少对这些主题进行合理的讨论,我们将不胜感激。

    基本上有两种情况:新鲜陈旧

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

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

    陈旧数据 如果你能负担得起陈旧的数据,事情就会变得容易得多。为了避免查询开销,可以存储重复的数据。为了避免维护重复数据,您不需要存储重复数据。至少不积极

    在这个场景中,您还需要只存储文档之间的引用。然后使用一个周期性的map reduce作业生成重复数据。然后可以查询单个map reduce结果,而不是单独的集合。这样可以避免查询开销,但也不必查找数据更改

    总结
    仅存储对其他文档的引用。如果您负担得起陈旧数据,请使用定期映射减少作业生成重复数据。避免维护重复数据;它很复杂而且容易出错。

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

    @Niels在这里有一个很好的总结,但我认为公平地说,你可以“欺骗”

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

    只需使用您想要的显示内容,如“商店名称”。因此,您的用户对象将如下所示:

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

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

    要回答您的直接问题:

  • 没有重复的
  • 没有重复的
  • )()

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

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

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

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

    +1当数据是由现有数据定期生成时,这是一种很好的方法。如果手动插入额外的数据,还必须手动更新。当然,对于那些不太可能改变的东西,比如商店名称,这不是一个问题。好的,一般来说,这对我来说是有意义的。我唯一不完全清楚的是,对于您描述的map-reduce-result情况,似乎假设所有数据都需要相同的新鲜度。在这里的示例中,用户数据必须是新鲜的,但用户的存储名称数据可能是过时的。因此,我不想从周期性映射reduce中读取用户数据和存储数据,因为用户数据不能过时。那么,这是否会迫使我完全进入“新鲜”场景呢?@Jim:如果部分数据(在本例中是访问的商店名称)可能已过时,您可以使用。在商店中更新商店名称时,请记住也要更新客户文档。@NielsvanderRest能否详细解释一下map reduce?我不熟悉“过时”和“新鲜”数据术语。这些术语是什么意思?等等!那么,这和RDBMS有什么区别呢?与Mongo一起在一个大项目中工作,如果认为这是正确的方法,我觉得这个答案非常令人失望。只要使用引用,Mongo就比任何关系数据库都慢。我试图通过检查复制数据的最佳方式来解决这个问题,我看到的只是人们告诉我要像在关系数据库中那样做。。。那么,为什么MongoDB是为?