【发布时间】:2019-05-08 17:07:28
【问题描述】:
我正在构建一个 DynamoDB 应用程序,该应用程序最终将为大量(数百万)用户提供服务。目前应用的项目架构很简单:
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
email: "foo@foo.com",
... other attributes ...
}
当有新用户注册时,或者如果用户想通过电子邮件地址查找其他用户,我们需要通过email 而不是userId 来查找用户。使用当前架构很简单:只需使用以email 作为分区键的全局二级索引。
但我们希望为每个用户启用多个电子邮件地址,而 DynamoDB Query 操作不支持 List-typed KeyConditionExpression。因此,每次用户注册或希望通过电子邮件地址查找其他用户时,我都会权衡几个选项以避免昂贵的Scan 操作。
以下是我计划更改的内容,以便为每个用户启用额外的电子邮件。这是一个好方法吗?有更好的选择吗?
- 添加一个排序键列(例如
itemTypeAndIndex)以允许每个userId有多个项目。
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
itemTypeAndIndex: "main", // sort key
email: "foo@foo.com",
... other attributes ...
}
- 如果用户添加第二封、第三封等电子邮件,则为每封电子邮件添加一个新项目,如下所示:
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
itemTypeAndIndex: "Email-2", // sort key
email: "bar@bar.com"
// no more attributes
}
仍然可以使用相同的全局二级索引(以
email作为分区键)来查找主要和非主要电子邮件地址。如果用户想要更改他们的主要电子邮件地址,我们将交换“主要”和“非主要”项目中的
email值。 (现在 DynamoDB 支持transactions,这样做会比以前更安全!)如果我们需要删除用户,我们必须删除该
userId的所有项目。如果我们需要合并两个用户,那么我们必须合并该userId的所有项目。-
相同的方法(具有相同
userId但排序键不同的新项目)可用于其他需要为Query-able 的 1-user-has-many-values 数据
这是一个好方法吗?有没有更好的办法?
【问题讨论】:
-
贾斯汀,为了搜索属性,我强烈建议不要使用 DynamoDB。我不是说,你可以做到这一点。但是,如果您选择这个根目录,我看到一些问题最终会出现在您的道路上。
-
@mango - 你预见到什么问题?
-
我不小心在评论中写下了我的答案。我在答案部分添加了详细答案。我希望这会有所帮助。
标签: amazon-web-services amazon-dynamodb dynamodb-queries