DynamoDB 1个大表还是多个小表?

时间:2019-02-27 01:34:21

标签: amazon-web-services database-design amazon-dynamodb

我目前面临一些有关数据库设计的问题。目前,我正在开发一个API,可让用户执行以下操作:

  • 创建帐户(1个用户拥有1个帐户)
  • 创建个人资料(1个帐户拥有1-n个个人资料)
  • 让个人资料上传2种类型的商品(1个个人资料拥有0-n个商品;这些商品的类型和用途不同)

调用API方法会触发AWS Lambda在DynamoDB表中执行请求的操作。

我当前的计划如下:

enter image description here

应该可以通过指定时间范围和配置文件ID来查询项目。但是我认为我的设计完全违背了DynamoDB的目的。 AWS文档说,设计良好的产品只需要一张桌子。

  • 在一个表中实现此架构的好方法是什么?
  • 使用当前设计是否有缺点?
  • 您将在当前设计和单表方法中指定什么作为主/分区/排序键/辅助索引?

1 个答案:

答案 0 :(得分:2)

假设您需要能够进行以下查询,我将给出此答案。

  • 提供一个帐户,找到所有个人资料
  • 提供个人资料,找到所有商品
  • 给出个人资料和特定的ItemType,找到所有项目
  • 给出项目,找到拥有的配置文件
  • 提供个人资料,找到拥有的帐户

DynamoDB的优点之一(也许也是个祸根)是它几乎没有架构。您需要为表中的每个项目都具有必填的“主键”属性,但是所有其他属性都可以是您喜欢的任何东西。为了仅使用一个表进行DynamoDB设计,通常需要习惯在同一表中混合对象类型的想法。

话虽如此,这是您的用例的一种可能模式。我的建议是假设您使用UUID之类的标识符。

分区键是一个字段,简称为pkey(或任何您想要的字段)。我们也将其称为排序键skey(但同样,它并不重要)。现在,对于一个帐户,pkey的值为Account-{{uuid}},而skey的值将相同。对于配置文件,pkey的值也是Account-{{uuid}},但是skey的值是Profile-{{uuid}}。最后,对于项目,pkeyProfile-{{uuid}},而skeyItem-{{type}}-{{uuid}}。对于项目的所有属性,不必担心,只需使用您要使用的任何属性即可。

由于“父”对象始终是分区键,因此只需查询父对象的ID,即可获得任何“子”对象。例如,您要获取配置文件的所有“ ItemType2”的关键条件表达式将是

pkey = “Profile-{{uuid}}” AND begins_with(skey, “Item-Type2”)

在此架构中,您的GSI与表具有相同的键,但是相反。您可以在GSI中查询“ Item-{{type}}-{{uuid}}”以获取拥有的个人资料,与此类似,使用Profile可以获取拥有的帐户。

我在这里说明的是adjacency list pattern。 DynamoDB也有一篇文章描述了如何使用composite sort keys for hierarchical data,它也适用于您的数据,并且取决于您的预期查询,它可能比使用邻接表更合适。

您不必将所有内容都放在一个表中。是的,DynamoDB建议这样做,但确保您的应用程序正确且可维护更为重要。如果有多个表意味着编写无缺陷的应用程序要容易些,那么请使用多个表。