Cross-links/updates NoSQL 数据库中的文档之间
Cross-links/updates between documents in NoSQL database
出于多种原因,我目前正在考虑迁移到 NoSQL 数据库以 store/manage 一组 "scorecards"。由于记分卡是一个简单的 table,区域的行和 metrics/indicators 的列。一个月的简单记分卡文档可能如下所示:
{
"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"}]
]
}
导致此渲染 table:
| 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
)属性。鉴于结构可能已更改,我怎样才能最有效地进行此更新?我怎样才能 "linked" 细胞?
在 RDBMS 中,我会规范化另一个 table 中的值并链接 valueId。但是,由于任何记分卡都可以有很多值,我假设将 valueIds 存储在记分卡文档中并在第二步中检索所有值真的很低效吗?!
我还没有决定使用 NoSQL DB 提供程序。当前最喜欢的是 CouchDb,但也可以是 MongoDB 或 DocumentDB。后端在 ASP.NET WebAPI 中实现。
大多数 NoSQL 数据库不支持多个记录之间的 JOIN
s - 因此您有几种不同的方式来建模关系。
规范化
正如您提到的,您可以将软link 留给另一个文档...然后通过后续查询解析引用。
通常,您会对希望针对写入进行优化的数据进行规范化。
注意: 在 DocumentDB 中,您可以通过使用 stored procedure 来降低后续查询上下文中与多个网络请求相关的成本。这允许您将一系列操作作为单个网络请求执行。
去规范化
或者,您可以将相关数据嵌入为 JSON 对象。这消除了通过后续查询解决引用的需要;但在改变数据时可能会引入复杂性(例如,将写入分散到多个记录)。
通常,您会规范化要针对读取优化的数据。
为什么不两者兼而有之?混合方法
您也可以采用混合方法。对相当静态或经常阅读的字段子集进行反规范化;然后规范化经常写入或不经常读取的字段。
参考资料
如需更深入的信息,我建议您查看:
- DocumentDB documentation on modeling data - 此信息可在其他文档数据库中重复使用。
- This Whosebug answer 详细讨论了规范化与去规范化数据之间的权衡。
出于多种原因,我目前正在考虑迁移到 NoSQL 数据库以 store/manage 一组 "scorecards"。由于记分卡是一个简单的 table,区域的行和 metrics/indicators 的列。一个月的简单记分卡文档可能如下所示:
{
"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"}]
]
}
导致此渲染 table:
| 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
)属性。鉴于结构可能已更改,我怎样才能最有效地进行此更新?我怎样才能 "linked" 细胞?
在 RDBMS 中,我会规范化另一个 table 中的值并链接 valueId。但是,由于任何记分卡都可以有很多值,我假设将 valueIds 存储在记分卡文档中并在第二步中检索所有值真的很低效吗?!
我还没有决定使用 NoSQL DB 提供程序。当前最喜欢的是 CouchDb,但也可以是 MongoDB 或 DocumentDB。后端在 ASP.NET WebAPI 中实现。
大多数 NoSQL 数据库不支持多个记录之间的 JOIN
s - 因此您有几种不同的方式来建模关系。
规范化
正如您提到的,您可以将软link 留给另一个文档...然后通过后续查询解析引用。
通常,您会对希望针对写入进行优化的数据进行规范化。
注意: 在 DocumentDB 中,您可以通过使用 stored procedure 来降低后续查询上下文中与多个网络请求相关的成本。这允许您将一系列操作作为单个网络请求执行。
去规范化
或者,您可以将相关数据嵌入为 JSON 对象。这消除了通过后续查询解决引用的需要;但在改变数据时可能会引入复杂性(例如,将写入分散到多个记录)。
通常,您会规范化要针对读取优化的数据。
为什么不两者兼而有之?混合方法
您也可以采用混合方法。对相当静态或经常阅读的字段子集进行反规范化;然后规范化经常写入或不经常读取的字段。
参考资料
如需更深入的信息,我建议您查看:
- DocumentDB documentation on modeling data - 此信息可在其他文档数据库中重复使用。
- This Whosebug answer 详细讨论了规范化与去规范化数据之间的权衡。