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

bau*_*sta 2 database-design amazon-web-services amazon-dynamodb

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

  • 创建一个帐户(1个用户拥有1个帐户)
  • 创建一个配置文件(1个帐户拥有1-n个配置文件)
  • 让配置文件上传2种类型的项目(1个配置文件拥有0-n个项目;这些项目的类型和用途不同)

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

我当前的计划如下所示:

在此处输入图片说明

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

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

Mat*_*ope 5

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

  • 给定一个帐户,找到所有配置文件
  • 给定一个配置文件,找到所有项目
  • 给定一个Profile和一个特定的ItemType,找到所有Items
  • 给定项目,找到拥有的配置文件
  • 给定个人资料,找到拥有的帐户

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

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

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

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

pkey = “Profile-{{uuid}}” AND begins_with(skey, “Item-Type2”)
Run Code Online (Sandbox Code Playgroud)

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

我在这里说明的是邻接列表模式。DynamoDB还提供了一篇文章,描述如何对层次数据使用复合排序键,该也适用于您的数据,并且取决于您的预期查询,它可能比使用邻接表更合适。

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