【问题标题】:Multiple Joins In CouchDBCouchDB 中的多个连接
【发布时间】:2023-03-27 18:42:02
【问题描述】:

我目前正在尝试确定 CouchDB 是否适合我的用例,如果适合,如何。我的情况类似于以下:

第一组文件(我们称它们为公司):

{
    "_id" : 1,
    "name" : "Foo"
}

{
    "_id" : 2,
    "name" : "Bar"
}

{
    "_id" : 3,
    "name" : "Baz"
}

第二组文档(我们称之为项目):

{
    "_id" : 4,
    "name" : "FooProject1",
    "company" : 1
}

{
    "_id" : 5,
    "name" : "FooProject2",
    "company" : 1
}
...
{
    "_id" : 100,
    "name" : "BazProject2",
    "company" : 3
}    

第三组文档(我们称之为事件):

{
   "_id" : "300",
   "project" : 4,
   "description" : "...",
   "cost" : 200
}

{
   "_id" : "301",
   "project" : 4,
   "description" : "...",
   "cost" : 400
}

{
   "_id" : "302",
   "project" : 4,
   "description" : "...",
   "cost" : 500
}
   ...

所以简而言之,每个公司都有多个项目,每个项目都可能有多个事件。我对数据建模的一个原因是,我主要来自 SQL 背景,因此建模可能完全不合适。第二个原因是,我想通过使用 couchdb 提供的 REST-API 非常轻松地添加新事件。所以事件必须是单个文档。

但是,我现在想获得一个视图,以便我计算每家公司的总成本。我可以使用 map-reduce 和链接文档轻松定义视图,这些文档可以让我了解每个项目的总金额。但是,一旦我处于项目级别,我就无法进一步达到公司级别。

这可能使用 couchDb 吗?这种汇总数据听起来像是 map-reduce 的完美用例。在 SQL 中我只会做一个三表连接,但似乎在 couchDb 中我能得到的最好的是两表连接。

【问题讨论】:

  • 您不能(或至少不应该)在 CouchDB 中进行任何联接。您可以使用列表函数来合并相邻的行(排序规则),但其他任何事情都会破坏您的性能。

标签: join couchdb nosql


【解决方案1】:

如前所述,您不能在 CouchDb 中进行联接,但这不是限制,这是一个邀请您思考您的问题并以不同的方式处理它们。在 CouchDb 中执行此操作的正确方法是定义数据结构,例如:IncidentReference 由以下组成:

  • 项目编号
  • 还有公司ID

这样您的数据将如下所示:

{
   "_id" : "301",
   "project" : 4,
   "description" : "...",
   "cost" : 400,
   "reference" : {
         "projectId" : 1,
         "companyId" : 2
   }
}

这很好。一旦你有了它,你就可以使用 Map/Reduce 来轻松实现你想要的任何东西。一般来说,您需要考虑查询数据的方式。

【讨论】:

  • 据我了解,从 SQL 的角度来看,您必须真正放弃任何形式的规范化?因为有了这个事件参考,我现在将 projectId 和 companyId 都存储在参考中,尽管项目已经包含公司(重复数据)。那么防止这些数据变得不一致的最佳方法是什么?
  • 一般来说,你仍然需要小心非规范化,例如,如果你对客户名称进行非规范化,并且这个名称发生了变化,这将变得难以管理。但是,根据需要拥有对其他实体的尽可能多的引用(标识符)通常是安全的。如果你仔细想想,这些引用变得过时是极其罕见的(事件怎么可能不再属于这个项目?或者这家公司)。只需确保这些引用参与定义您的文档的身份,身份不会改变:)
猜你喜欢
  • 1970-01-01
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多