13

根据 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 操作,我们需要扫描所有表,然后按用户角色过滤结果,这是无效的。如何改进?很自然 - 让我们为每个用户类型拥有自己的表格!然后我们将从管理 API 扫描经理列表,并从经理一号扫描工人列表。

我使用 DynamoDB 快一年了,仍然无法使用。对我来说,现实情况是,对于现实生活场景,排序键是你永远无法使用的(我唯一的真实情况是同时访问属于不同类型的两个用户的“协议”之类的项目,所以主键是{partion:“managerId”,排序:“userId”},二级全局索引是{partition:“userId”,排序:“managerId”},所以我可以有效地查询所有特定的经理协议列表或所有特定的用户协议列表仅提供查询的相应经理或用户 ID。该方法在此处的文档中进行了讨论:https ://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html )。

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

4

2 回答 2

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 会为您工作。

于 2019-12-12T20:04:11.520 回答
0

你可以有一个像

user_id, role, <other columns>

在哪里

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

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

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

如果您有任何问题,请告诉我

于 2019-08-16T07:09:55.980 回答