我正在构建一个最终将为大量(数百万)用户提供服务的 DynamoDB 应用程序。目前,该应用的项目架构很简单:
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
email: "foo@foo.com",
... other attributes ...
}
当新用户注册时,或者如果用户想通过电子邮件地址查找其他用户,我们将需要查找用户 byemail
而不是 by userId
。使用当前模式很容易:只需使用全局二级索引email
作为分区键。
但是我们希望为每个用户启用多个电子邮件地址,并且 DynamoDBQuery
操作不支持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 支持事务,这样做会比以前更安全!)如果我们需要删除一个用户,我们必须删除该用户的所有项目
userId
。如果我们需要合并两个用户,那么我们必须为此合并所有项目userId
。相同的方法(具有相同
userId
但不同排序键的新项目)可用于其他需要Query
-able的 1-user-has-many-values 数据
这是一个好方法吗?有没有更好的办法?