DynamoDB邻接表模式

5
我正在尝试更好地了解在AWS DynamoDB中使用邻接列表模式进行多对多(m:n)关系设计。查看AWS文档https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html,我们有一个发票(Invoice)和账单(Bill)实体的示例,具有m:n关系。

enter image description here

我知道可以通过读取单个分区获取与特定发票相关的所有账单的详细信息。例如,我可以查询Invoice-92551,并根据分区中的附加项目了解与其关联的2个账单的某些属性。
我的问题是,要获取这2张账单的完整属性,我需要做什么?这是否需要使用我从发票分区派生的ID进行2个附加查询,还是我错过了其他模式?
附加细节 参考屏幕截图中Bill项目的2种不同描述:
• 发票分区中的账单项目:“此发票中此账单的属性” • 自己的分区中的账单项目:“此账单的更多属性”
这是否意味着我的发票分区应包括我想要通过最少的查询访问的任何账单属性?我最初认为账单分区将包含我想要的大部分内容,但如果我想通过发票访问它们,那就不太合理了。
2个回答

2
你有两个选择:发出多个查询或重复某些账单数据。当你查询一个发票及其账单时,你会得到以下内容:
  • 此发票的更多属性,以及
  • 在此发票中的此账单的属性。
你将不会为任何账单获得“此账单的更多属性”。为了获取这些属性,必须查询账单本身。你可以发出单独的GetItem查询,或使用账单ID查询限制每次查询100个账单的单个BatchGetItem查询。
或者,你可以将“此账单的更多属性”的一些值复制到每个invoice-bill项中,以避免第二次查询,但代价是增加存储和插入/更新复杂性。

0
不需要额外查询 - 除非您只请求特定属性("project"),否则您的查询将检索账单的所有属性及其键。DynamoDB将每个分区一起存储在单个节点上,因此获取整个分区是高效的。该分区由其"分区键"(发票号码)定义。分区包含一堆"项目"(您的账单),每个项目都有自己的"排序键"(账单ID)和任意数量的"属性"。当DynamoDB读取分区时,它按顺序读取那些项目及其所有属性,并且除非您明确要求不返回它们,否则可以返回所有这些项目。请注意,即使您仅请求返回这些属性的子集(一个"projection"),Amazon仍然需要从磁盘中读取它们,您仍然需要为此支付I/O费用。

那么,如果订单项中的发票分区中有我需要的所有属性,这将起作用,对吗?AWS文档让它看起来像订单有自己的分区,具有其特定属性,而发票分区中的属性仅与发票相关。我假设这意味着我需要在两个地方都复制所有属性? - bingles
恐怕我没有完全理解亚马逊的例子。仅具有特定排序键的单个“项”而不是“分区”具有其他属性。上面的示例还提到他们使用 GSI。GSI(全局二级索引)允许您将所有相同的属性复制到由不同键索引的项目中。也许这个 GSI 就是意味着您不需要“在两个位置都复制所有属性”的东西 - 这正是 GSI 为您所做的。 - Nadav Har'El
我认为我理解的是,在单个分区读取中没有魔法方法可以包含来自其他分区的数据。GSI 从读取角度有效地重新分区,但如果我从发票 ID 开始并获取相关账单,我只能访问该分区中存在的任何属性,然后必须重新发出查询以获取其他分区中的数据?或者,我可以在我的 InvoiceBill 项目中包含更多属性以在第一次读取时访问它们。 - bingles
我有同样的问题。这让我想知道选择邻接列表模式相比于为账单使用不同的表格有什么优势。无论如何,它都需要额外的查询。 - Kyle
1
我相信你误解了这个问题。查询 invoice 时,您将不会获取到来自 bill 数组的属性,只会得到 invoice-bill 数组的属性。 - David Harkness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接