假设我有一个包含id
和timestamp
属性的用户表。我希望能够查询这两个参数。如果我正确理解文档,有两种方法可以使用DynamoDB:
id
作为哈希值并使用timestamp
作为范围来定义哈希+范围主键。id
定义仅哈希主键,并使用timestamp
定义全局二级索引。每种方法有哪些优点和缺点?
答案 0 :(得分:11)
使用id作为哈希和时间戳,定义哈希+范围主键 范围。
当你有效地id
你的哈希键和timestamp
你的范围键时,你允许他们两个都形成一个'复合主键'。
换句话说,您的DynamoDB架构将允许以下数据(注意'john'重复三次?)
id | timestamp
--------|-------------------------
john | 2014-04-28T07:53:29.000Z
john | 2014-04-28T08:53:29.000Z
john | 2014-04-28T09:53:29.000Z
mary | 2014-04-28T07:53:29.000Z
jane | 2014-04-28T07:53:29.000Z
如果这不是你想要的,那么id
和timestamp
上的哈希+范围分别不是你想要的。
使用id定义仅哈希主键并定义全局辅助键 索引使用时间戳。
在id
上使用仅限哈希的主键,表明id
属性应该是唯一的。然后,只需在GSI
上应用timestamp
哈希,您就可以查询与特定ids
相关的timestamp
列表。
这种方法的好处是,它绝对是您用例的正确解决方案。 #1是滥用范围密钥(除非您打算确保在应用程序级别id
不重复,这可能是一个坏主意)。
使用GSI
的缺点是:
GSI
个,所以明智地选择需要索引的内容,因为GSI
只能在创建表时指定,不能更改。GSI
将需要您支付额外费用,因为您需要为其分配预配吞吐量。GSI
最终是一致的,这意味着DynamoDB不保证与表的散列键关联的时刻数据写入DB,数据的GSI
散列键立即可用于查询。该文档指出这通常是立即的,但可能需要几秒钟才能使GSI
哈希键变为可用。答案 1 :(得分:5)
This answer可能有一些用处,但你对于完成它的两种方式是正确的。
假设您使用id
作为哈希键,那么为了仅使用时间戳检索项目,您需要一个全局二级索引。您仍然可以将timestamp
作为范围键,这将非常有用,因为DynamoDB将使用它来按id
对查询结果进行排序。
使用全局二级索引的主要缺点是您需要在桌面上提供额外的预配置吞吐量。
答案 2 :(得分:0)
我有类似的兴趣,并且正在考虑在一部分时间戳(例如,天或小时)上创建一个二级索引作为HASH,将Id作为RANGE创建,以允许针对特定时间片进行查询,但这会强制将时间片内的所有记录置于索引的同一分区中。
为了能够查询最新数据还是历史数据,Amazon建议使用多表设计方法-请参见https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-time-series.html。