目前我有一个包含以下字段的集合:
userId
otherUserId
date
status
对于我的Dynamo集合,我使用userId作为hashKey
,而rangeKey
我想使用date:otherUserId。通过这样做,我可以检索所有在好日期排序的userId条目。
但是,对于我的用例,我不应该有任何重复,这意味着我的集合中不应该有相同的userId-otherUserId
值。这意味着我应首先查询是否存在“成对”,如果需要则将其删除,然后插入,对吧?
编辑:
感谢您的帮助: - )
我的用例的目标是在userA访问userB的个人资料时存储。
现在,我想要做的查询如下:
答案 0 :(得分:2)
我认为你有很多选择,但这里有一个可能有效的假设你的应用程序是时间感知的,即你想在最后N分钟,几小时,几天等内查询交互。
hash_key = userA
range_key = [iso1860_timestamp][1]+userB+uuid
首先,uuid技巧是为了避免覆盖userA和userB之间完全同时发生的交互记录(可能会发生,具体取决于时钟的粒度/精度)。所以插入方式我们是安全的:没有重复,没有覆盖。
查询方面,以下是完成工作的方式:
- 以唯一的方式(=无双用户B)检索访问UserA配置文件的所有UserB,并按时间排序。
query(hash_key=userA, range_key_condition=BEGIN(common_prefix))
2013年1月所有互动的common_prefix
= 2013-01-01
这将检索时间范围内的所有记录,已排序(假设它们按正确的顺序插入)。然后在应用程序代码中过滤它们以仅保留与userB相关的那些代码。不幸的是,DynamoDB API不支持范围键条件列表(否则您可以通过传递额外的CONTAINS userB条件来节省一些时间)。
- 检索UserA和UserB的特定配对访问
query(hash_key=userA, range_key_condition=BEGINS(common_prefix))
如果我们可以假设您知道交互的时间戳,那么common_prefix
可以更精确。
当然,应该根据您将处理的数据流的属性来评估此设计。如果您(通常)可以为查询指定有意义的时间范围,那么它将快速受限于您在userA的时间范围内记录的交互次数。
如果您的应用程序不是那么面向时间 - 并且我们可以假设用户通常只有少量交互 - 您可以切换到以下架构:
hash_key = userA
range_key = userB+[iso1860_timestamp][1]+uuid
这样您就可以按用户查询:
query(hash_key=userA, range_key_condition=BEGIN(userB))
此替代方案将快速受限于userA的用户 - 所有时间范围内的用户B交互 ,根据您的应用程序,这可能是有意义的。
所以基本上你应该检查示例数据并估计哪个方向对你的应用程序有意义。通过在其他表中手动创建和维护索引,也可以加快两个方向(时间或用户)的速度 - 以更复杂的应用程序代码为代价。
(历史版本:避免使用基于时间的密钥覆盖记录的技巧)
在您的情况下,一个常见的技巧是使用生成的唯一ID(uuid
)对范围键进行后缀。这样,您仍然可以使用query
条件进行BETWEEN
次调用,以检索在给定时间段内插入的记录,并且您无需担心插入时的密钥冲突。