NoSQL数据库中文档之间的交叉链接/更新

时间:2015-06-27 22:44:01

标签: mongodb couchdb azure-cosmosdb

出于多种原因,我目前正在考虑转移到NoSQL DB来存储/管理一组记分卡"。记分卡是一个简单的表,其中包含用于指标/指标的区域和列的行。因为一个月的简单记分卡文件可能如下所示:

{
  "month": 1,
  "headers": ["Region", "# of page views", "# of unique visitors"],
  "data": [
     ["Region 1", {"value": 1000, "previousValue": 800, "arrow": "up" }, {"value": 100, "previousValue": 110, "arrow": "down"}],
     ["Region 2", {"value": 500, "previousValue": 600, "arrow": "down" }, {"value": 10, "previousValue": 11, "arrow": "down"}]
  ]
}

生成此渲染表:

|  Region  | # of page views | # of unique visitors |
|----------|-----------------|----------------------|
| Region 1 | 1000 (↑)        | 100 (↓)              |
| Region 2 | 500 (↓)         | 10 (↓)               |

每个月都会上传一张新的记分卡,即创建一个新文档。该记分卡可能具有不同的结构,例如

{
  "month": 2,
  "headers": ["Region", "# of page views", "# of comments"],
  "data": [
     ["Region 1", {"value": 1100, "previousValue": 1000, "arrow": "up"}, {"value": 5, "previousValue": null, "arrow": null}],
     ["Region 3", {"value": 1500, "previousValue": null, "arrow": null},{"value": 1, "previousValue": null, "arrow": null}]
  ]
}

导致

|  Region  | # of page views | # of comments |
|----------|-----------------|---------------|
| Region 1 | 1100 (↑)        | 5 (-)         |
| Region 3 | 1500 (-)        | 1 (-)         |

当我现在收到第1个记分卡的更新时,我还需要更新第2个月记分卡中的previousValue(以及arrow)属性。鉴于结构可能已更改,我如何才能最有效地进行此更新?我该如何联系"细胞?

在RDBMS中,我会将另一个表中的值规范化,并且只链接valueIds。但是,由于任何记分卡都可以包含很多值,我认为在记分卡文档中存储valueIds并在第二步中检索所有值实际上效率很低?!

我还没有决定使用NoSQL DB提供程序。目前最受欢迎的是CouchDb,但也可以是MongoDB或DocumentDB。后端在ASP.NET WebAPI中实现。

1 个答案:

答案 0 :(得分:2)

大多数NoSQL数据库不支持多个记录之间的JOIN - 因此您可以通过几种不同的方式来建模关系。

<强>正火

正如您所提到的,您可以将软链接留给另一个文档...然后使用后续查询解析引用。

通常,您需要规范化您希望优化写入的数据。

注意:在DocumentDB中,您可以使用stored procedure在后续查询的上下文中降低与多个网络请求相关的成本。这允许您将一系列操作作为单个网络请求执行。

<强>德正火

或者,您可以将相关数据嵌入为JSON对象。这消除了使用后续查询解析引用的需要;但是在改变数据时可能会引入复杂性(例如,将写入扇出到多个记录中)。

通常,您会规范化您希望优化读取的数据。

为什么不两者兼而有之?混合方法

你也可以采取混合方式。对相当静态或经常读取的字段子集进行去规范化;然后规范化经常写入或不经常读取的字段。

<强>参考

有关更深入的信息,我建议您查看: