如何设计关键架构以使每个应用程序只有一个DynamoDB表?

时间:2018-09-11 14:51:38

标签: amazon-web-services amazon-dynamodb dynamodb-queries

根据DynamoDB文档:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html

“您应该在DynamoDB应用程序中维护尽可能少的表。大多数设计良好的应用程序仅需要一个表。”

但是根据我的经验,由于分区键的设计,您总是必须做相反的事情

让我们考虑下一种情况。我们有几个用户角色,例如“ admin”,“ manager”,“ worker”。管理员通常的工作流程是处理CRUD管理员数据,其中读取操作不是要获取一个管理员,而是要获取所有管理员列表。经理也一样-他CRUD工人数据。 对于这两种情况,我们只有两种密钥使用情况:

  • 获取所有项目的列表(项目键无关紧要)
  • 使用完整键处理特定项目。

自然,我们应该有统一分布的分区键(如文档所强调),因此我们不能为其选择用户角色,而应使用用户ID。由于我们已经有一些随机ID作为分区键,因此根本不需要排序键,因为它根本不起作用-我们已经仅通过使用分区键部分就可以访问一个用户。在这一点上,我们意识到用户ID对于CUD操作来说就像是一个咒语,但是对于每个R操作,我们需要扫描所有表,然后按用户角色过滤结果,这是无效的。如何改善呢?很自然-让我们为每种用户类型拥有自己的表!然后,我们将通过admin API扫描经理列表,并从经理一扫描工作者列表。

我使用DynamoDB差不多一年了,但仍然无法使用它。对我来说,现实是在现实生活中,排序键是您永远无法使用的(我唯一的真实案例就是同时访问属于不同类型的两个用户的“协议”之类的项目,因此主键是{partion:“ managerId”,sort:“ userId”},辅助全局索引是{partition:“ userId”,sort:“ managerId”}这样我就可以有效地查询所有特定的经理协议列表或所有特定用户协议列表仅提供查询的相应管理者或用户ID。此方法在文档https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html中进行了讨论。

我觉得我根本不了解这个概念。对于所提供的示例,对于两种用户类型,仅使用一个 DynamoDB表,什么是关键架构的有效方法?

2 个答案:

答案 0 :(得分:1)

在这种情况下,您似乎需要一个全局二级索引(https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html),其中分区键是用户角色。这样,您可以通过该UserRoleIndex查询具有特定角色的所有用户,并借助用户ID上的排序键,在该角色中挑选出一个特定用户。

或者,如果您从头开始创建一个新表,则可能甚至不需要索引(除非您在删除用户时不知道用户的角色)。您可以使用“复合主键”(https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey),其中分区键和排序键将与我上面建议的索引相同。

使用与您在问题中使用的相同的符号,我建议使用{ partition: "userRole", sort: "userId" }

有时很难理解DynamoDB,而且在某些情况下,传统SQL数据库更有意义。 AWS re:Invent 2018的这段视频非常适合理解两者之间的区别:https://www.youtube.com/watch?v=HaEPXoXVf2k&feature=youtu.be

不过,对于您而言,您似乎拥有非常清晰的访问模式,因此DDB会为您工作。

答案 1 :(得分:0)

您可以拥有类似的模式

user_id, role, <other columns>

其中

  • user_id =哈希键
  • 角色= GSI哈希键

这样,您可以通过查询GSI来读取并获取所有经理的名单

使用 GSI ,DynamoDb会创建另一个表并对其进行维护,因此您无需维护多个表。

让我知道您是否有任何疑问