DocumentDB-嵌入vs参考vs中间方式

时间:2018-06-23 06:15:07

标签: azure-cosmosdb

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

进行说明

因此,Order具有OrderLines,而OrderLines包含Products。 (逻辑上)

在documentDB中,Order可以这样表示:

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

在这种情况下,将嵌入OrderLines并引用Products(在{{1时,附加name字段是Product名称的快照}}正在创建)。

现在我们来查询:OrderLine

在此设置中,该查询应遍历所有How much of a Product with id=abc have i sold between date1 and date2?> Orders以在给定行中找到OrderLines。听起来不是最佳。 其他解决方案是通过引用productId来平化文档,而不是将其嵌入OrderLines中。这对于此查询很有用,但随后查询完整的Order会变成2个查询。

第三种选择是将Order记录保留在numberOfSales文档中,以便我们为每个产品保留Product。每次创建runningBalance时,都需要执行2步写操作:编写订单本身并进行一次Order文档更新。

此刻,我主要倾向于使用每种产品的运行平衡来解决第三个解决方案,但是不确定我是否缺少什么?这有什么大问题吗?或者,是否有一些推荐/更好/其他方式?

1 个答案:

答案 0 :(得分:0)

IMHO,最好的方法是最重要的事情-识别PartitionKey 。它影响了开发的许多方面,因此在构建其余模式之前首先要研究一下。有某些规则-

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

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

现在是开始设计模式细微差别的时刻了。因此,一般而言,制定符合上述最佳做法的方案。如果最终有多种选择,请选择一种“更适合”您的选择:)


这里是如何设计架构的示例。

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

它给您- a)一个查询以获取订单详细信息 b)可以缩小查询给定时间范围内购买产品数量的查询分成一个部分。假设您有日期字段的索引,查询的性能应该满足您。 c)您可以使用bulk-api将多个记录插入第三个集合中。 d)无需在每次有新订单时更新(替换和插入)产品记录。 e),当然,要权衡一下是自己同步Orders和ProductOrders集合,以及少量(?)数据重复。

这只是众多选择之一。如果写入率较低且订单数量巨大,则您甚至可以为每个年月组合创建一个集合。了解最佳做法,您的生产工作量和实验应该可以为您提供最佳解决方案。