尽管
全局二级索引
似乎符合您的要求,但是将
时间戳
相关信息作为
哈希键
的一部分会很可能创建所谓的“热分区”,这是极其不可取的。
访问不平衡将发生在最近的项目将以比旧项目更频繁的方式检索。这不仅会影响您的性能,还会使您的解决方案变得不太划算。
从文档中查看一些详细信息:
例如,如果表具有非常少量的大量访问的分区键值,甚至可能只有一个非常频繁使用的分区键值,则请求流量集中在少量分区上-可能仅有一个分区。如果工作负载严重不平衡,意味着它过度集中在一个或少数几个分区上,则请求将无法达到总体预配吞吐量水平。为了充分利用DynamoDB吞吐量,请创建具有大量不同值的分区键,并且请求的值相对均匀地请求,尽可能随机。
根据所述,
id
确实似乎是您的
Hash Key
(又称
Partition Key
)的不错选择,因为 GSI 键在分区方面的工作方式与之相同。另外,当您通过提供整个
Primary Key
来检索数据时,性能会得到高度优化,因此我们应该尽可能找到提供该解决方案的方法。
我建议创建单独的表来存储基于最近更新时间的主键。您可以根据最适合您用例的细粒度将数据分段到表中。例如,假设您想按天分段更新:
a. 您的每日更新可以存储在具有以下命名约定的表中:
updates_DDMM
b.
updates_DDMM
表仅包含
id
(其他表的哈希键)
现在假设最新的应用程序刷新日期是 2 天前(04/07/16),您需要获取最近的记录,则需要:
i. 扫描表格 updates_0504
和 updates_0604
,以获取所有哈希键。
ii. 最后,通过提交一个带有所有获取的哈希键的 BatchGetItem
,从包含纬度/经度、名称等信息的主表中获取记录。
BatchGetItem
超级快速,可以像其他操作一样完成任务。
有人可能会认为创建额外的表格会增加整体解决方案的成本... 嗯,使用 GSI
本质上是复制您的表格(如果您正在投影所有字段),并为所有 ~2k 条记录添加额外的成本,无论它们是否最近更新过...
创建这样的表格似乎是违反直觉的,但实际上,当处理时间序列数据时,这是最佳实践(来自 AWS DynamoDB 文档):
[...] 应用程序可能会在表中所有项目上显示不均匀的访问模式,其中最新的客户数据更为相关,您的应用程序可能更频繁地访问最新的项目,并且随着时间的推移,这些项目被访问的次数越来越少,最终较旧的项目很少被访问。如果这是已知的访问模式,则在设计表模式时可以考虑它。您可以使用多个表来存储这些项目,而不是将所有项目存储在单个表中。例如,您可以创建用于存储每月或每周数据的表。对于存储来自最新月份或周的数据的表,其中数据访问率很高,请请求更高的吞吐量;对于存储较旧的数据的表,您可以降低吞吐量并节省资源。
通过将“热门”项目存储在具有较高吞吐量设置的一个表中,将“冷门”项目存储在具有较低吞吐量设置的另一个表中,您可以节省资源。您可以通过简单地删除表来删除旧项目。您还可以选择将这些表备份到其他存储选项,例如 Amazon Simple Storage Service(Amazon S3)。删除整个表比逐个删除项目要高效得多,因为您需要进行与放置操作相同数量的删除操作,从而将写入吞吐量翻倍。
Source:
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html
我希望这有所帮助。敬礼。