我一直在寻找DynamoDB来存储一些数据,因为它看起来像是一种经济高效的解决方案,但是经过一些研究,我认为它可能不适合我的用例,因为我无法找到相关的唯一值分区和排序键。
我的数据是一系列有关各种植物(例如植物)自然事件的记录。有人注意到山毛榉树的叶子出现的日期和位置。
{
"species": "Beech",
"event": "Budburst",
"year": 2015,
"season": "Spring",
"date": "12/04/2015",
"latitude": "0.00000",
"longitude": "40.000"
}
该应用程序的主要查询将是获取特定年份中某个事件的某个物种的所有数据:
端点:events/:species/:event-type/:year
这可能会返回几千个事件,然后可以在地图中显示它们。
如果这是MongoDB,则可以在species+eventType+year
的复合字段上创建索引。它不是唯一的索引,但是至少只扫描几千个结果,而不是整个表,因此也不错。
但是,我不确定如何在DynamoDB中实现相同的目的,或者甚至不可能,因为分区键或分区+排序键组合似乎必须唯一。
使这项工作唯一的方法是使分区键的唯一事件ID递增,然后将species+eventType+year
字符串作为排序键吗?
如果还有其他模式,我将不胜感激。
感谢阅读。
答案 0 :(得分:1)
听起来自然的主键是将种类作为哈希键,将eventType + timeStamp作为排序键。 (使用ISO-8601作为时间戳,以便您可以在KeyConditionExpression中使用begins_with
函数进行查询。)
如果给定物种和事件类型可能同时存在多个事件,或者您只是缺少事件的精确时间戳,则可以使用UUID作为哈希键,并创建一个自primary keys do not have to be unique in a GSI起,以物种为哈希键并以eventType + year或什至物种+ eventType + year为哈希键的GSI。
此外,这是一个有用的相关问题,询问“ How to query DynamoDB by date (range key), with no obvious hash key?”
答案 1 :(得分:1)
您可以执行以下操作:
{
"species+event+year": "BeechBudhurst2015",
"eventId": 1111-2222-3333-4444
"species": "Beech",
"event": "Budburst",
"year": 2015,
"season": "Spring",
"date": "12/04/2015",
"latitude": "0.00000",
"longitude": "40.000"
}
为每个事件创建一个UUID。无论如何,这都是一个好习惯,应该总有一些东西可以唯一地标识一个事件。
您已经确定了,创建一个物种+事件+年份的复合属性。
将物种+事件+年作为分区键,将eventId(UUID)作为范围键。
进行Query时,只需提供分区键,即可为您提供特定年份特定事件的所有物种。
如果您想使用Get item来检索单个事件,则需要同时指定分区键和范围键。
此设计经过高度优化,可获取物种+事件+年。如果您想优化其他查询,则可以考虑使用eventId的主分区键-我认为这将是更常见的设计。然后为每个优化的查询创建一个GSI(例如,GSI分区键种类+事件+年)。请注意,GSI分区键不必唯一,因此无需设置范围键即可使每个项目都唯一。使用GSI的不利之处在于您必须单独配置它们(即,这会花费您更多的钱)。