【发布时间】:2016-11-30 18:40:47
【问题描述】:
想象一下,您需要持久化可以用以下模式表示的东西:
{
type: String
createdDate: String (ISO-8601 date)
userId: Number
data: {
reference: Number,
...
}
}
type 和 createdDate 始终是定义/必需的,其他所有内容,例如 userId、data 以及 data 中的任何字段都是可选的。 type 和 createdDate 的组合不保证任何唯一性。数据中的字段数(当data 存在时)可能不同。
现在假设您需要针对以下结构进行查询:
- 给我
type等于某物的项目 - 给我
userId等于某物的项目 - 给我
typeANDuserId等于某物的项目 - 给我
userIdANDdata.reference等于某物的项目 - 给我一些
userId等于某物、type在值范围内以及data.reference等于某物的项目
在我看来,需要在表级别引入 HashKey 以唯一匹配项目。我唯一的选择是使用 UUID 生成器之类的东西。基于此,我无法从上述我需要的表中查询任何内容。 所以我需要创建几个全局二级索引来覆盖上述所有第五种情况,如下所示:
- 对于第一个用例,我可以创建 GSI,其中
type可以是 HashKey,createdDate可以是 RangeKey。正如我所提到的,从这里开始困扰我的是,这个复合键很有可能不是唯一的。 - 对于第二个用例,我可以创建 GSI,其中
userId可以是 HashKey,createdDate可以是 RangeKey 这里可能这个复合键可以唯一地匹配项目。 - 对于第三个用例,我可能有两种解决方案。要么创建第三个 GSI,其中
type可以是 HashKey,userId可以是 RangeKey。使用这种方法,我失去了对返回的数据进行排序的能力,并且同样担心,这个复合键不能保证唯一性。另一种方法是使用之前的两个 GSI 之一并使用 FilterExpression,对吗? - 对于第四个用例,我只有一个选项。使用以前的 GSI,
userId作为 HashKey,createdDate作为 RangeKey,并对data.reference使用 FilterExpression。无法在嵌套对象的字段上创建索引对吗? - 对于第五个用例,因为 IN 运算符仅通过 FilterExpression 支持(对吗?),唯一的选择是使用 GSI,
userId作为 HashKey,createdDate作为 RangeKey,并使用type和data.reference的 FilterExpression?
因此,作为这个问题的唯一亮点,我看到使用 GSI,userId 作为 HashKey,createdDate 作为 RangeKey。 但同样,userId 不是必填字段,它可以为 NULL。 HashKey 不能为 NULL 对吧?
最重要的是,如果复合键(HashKey 和 RangeKey)不能保证唯一性,这意味着使用索引中已经存在的复合键保存项目将默默地重写前一个项目,这意味着我将丢失数据?
【问题讨论】:
-
您的数据更新频率如何?
-
@HarshalBulsara 经常
-
我觉得你可以看看 CloudSearch 服务,它可能会有所帮助。
-
您能否详细说明一下,CloudSearch 是什么?为什么不使用常规 API 与 DynamoDB 交互?
-
云搜索是另一个 AWS 服务,它可以与 DynamoDB 集成用于搜索目的,因为您想查询您的非关键属性,再加上许多 GSI 没有任何意义
标签: amazon-web-services amazon-dynamodb