【问题标题】:DocumentDB - embed vs reference vs middle wayDocumentDB - 嵌入 vs 参考 vs 中间方式
【发布时间】:2018-06-23 06:15:06
【问题描述】:

我正在为 DocumentDB 数据库建模,并试图找出解决特定问题的最佳方法。 让我们用Order > OrderLine > Product example. 来说明它

所以,Order 包含 OrderLinesOrderLines 包含 Products。 (逻辑上)

在 documentDB 中,Order 可以表示,例如:

{
  id,
  title,
  date,
  lines:
  [
    { orderLineId, productId, name, quantity, price  },
    { orderLineId, productId, name, quantity, price  },
    { orderLineId, productId, name, quantity, price  }
  ]
}

在这种情况下,OrderLines 被嵌入,Products 被引用(添加的name 字段是Product 在创建OrderLine 时名称的快照)。

现在我们来一个查询:How much of a Product with id=abc have i sold between date1 and date2?

在此设置中,该查询应遍历所有Orders > OrderLines 以在给定行中找到productId。听起来不是最优的。 其他解决方案是通过引用OrderLines 来展平文档,而不是将它们嵌入到Order 中。这对这个查询很有用,但是查询完整的 Order 会变成 2 个查询。

第三种选择是在 Product 文档中保留 numberOfSales 记录,以便我们为每个产品保留 runningBalance。这需要为每个Order 创建两个步骤写入:一个用于订单本身,一个用于更新Products 文档。

目前,我主要倾向于第三种解决方案,每种产品都保持平衡,但不确定我是否遗漏了什么?这有什么大问题吗?或者,有什么推荐的/更好的/其他方式吗?

【问题讨论】:

  • >>" 这对这个查询很好,但是查询完整的 Order 会变成 2 个查询。" - 如果你把这 2 个放在同一个分区中,你可以编写存储过程来更快地执行这 2 个......使用第 3 个选项 - 你需要注意 order 的数据与 product.numberOfSales 数据一致。 .我认为方式取决于您需要执行每种类型的查询的频率..顺便说一句,有一个 FeedChange 选项,您可以使用它订阅您的集合中的文档更改并基于此 - 更新您的 product.numberOfSales 属性 - 所以您最终会收到 1 次订单创建电话

标签: azure-cosmosdb


【解决方案1】:

恕我直言,最好的方法是从最重要的事情开始 - 识别 PartitionKey。它影响开发的许多方面,因此在构建架构的其余部分之前,首先值得研究一下。这有一定的规则 -

  1. 确保您的 PartitionKey 允许您在分区上分发请求,而不是以“热”分区结束。通常首选具有较高基数的分区键。
  2. 由于 PartitionKey 定义了有效查询和事务的范围,因此请选择可让您缩小请求范围以避免跨分区/扇出请求的范围。
  3. 根据存储和吞吐量预测您的需求。请记住,逻辑分区的增长不能超过最大逻辑分区限制 10 GB。

除此之外,您还需要了解您的工作量。对于阅读量大的查询,请考虑您的热门查询,例如执行次数多于其他查询或(-并且)处理大量数据的查询。对于写入繁重的工作负载,请考虑事务和更新与插入(据我所知,还没有部分更新之类的东西)。

现在是时候开始设计架构的细微差别了。因此,总的来说,开发符合上述最佳实践的方案。如果您最终有多种选择,请选择更“适合”您的一种:)


以下是如何设计架构的示例。

  • 保持 Order 集合不变,将 orderid 设置为您的 PartitionKey。
  • 获取另一个用于保存产品记录的集合,productionid 为 PartitionKey。
  • 现在,创建第三个集合 - ProductOrders,您将在其中放置每个产品订单组合的记录,并创建集合的 productid PartionKey - {productid, orderid,date, ...}。

它为您提供 - a) 一个查询来获取订单详细信息 b) 可以缩小在给定时间范围内计算购买产品数量的查询到单个分区。假设您有针对 Date 字段的索引,则查询的性能应该让您满意。 c)bulk-api 用于将多条记录插入到第三个集合中,您可能需要查看它。 d) 每次有新订单时无需更新(替换和插入)产品记录。 e) 一个折衷方案当然是自行同步 Orders 和 ProductOrders 集合,以及少量(?)数据重复。

这只是众多选择之一。在写入率小而订单量大的情况下,您甚至可以为每个年月组合创建一个集合。了解最佳实践、您的生产工作负载和实验应该会引导您找到最佳解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多