DynamoDB:区间与全球二级指数



假设我有一个具有idtimestamp属性的用户表。我希望能够查询这两个参数。如果我正确理解文档,那么使用DynamoDB有两种方法:

  1. 使用id作为散列,timestamp作为范围来定义散列+范围主键
  2. 使用id定义仅散列主键,并使用timestamp定义全局辅助索引

每种方法的优点和缺点是什么?

定义一个hash+range主键,使用id作为hash,时间戳为范围。

通过使id成为Hash Key,使timestamp成为Range Key,您有效地创建了一个"复合主键"。

换句话说,DynamoDB模式将允许以下数据(注意,"john"重复了三次)

id (Hash) | timestamp (Range)
----------|-------------------------
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

您可以执行以下操作:

  1. GetItem基于id(哈希密钥)+timestamp(范围密钥)组合得到单个项
  2. Query以获得等于id(哈希密钥)的所有项目的列表

如果这不是您想要的,那么分别在idtimestamp上的hash+范围就不是您要寻找的。

使用id定义仅散列主键,并定义全局辅助密钥使用时间戳进行索引。

id上使用仅散列主键时,id必须是唯一的。

id (Hash) | timestamp (GSI Hash Key)
----------|-------------------------
john      | 2014-04-28T07:53:29.000Z
mary      | 2014-04-28T07:53:29.000Z
jane      | 2014-04-28T07:53:29.000Z

然后,通过仅在timestamp上应用GSI散列,您将能够查询特定timestampids列表。

这种方法的优点是,它绝对是您用例的正确解决方案#1是范围密钥的误用(除非您打算在应用程序级别确保id不重复,这可能是个坏主意)。

使用GSI的缺点是:

  1. 每个表最多只能有5个GSI,所以明智地选择您想要的索引DynamoDB Update Dec 2019-您现在可以为每个表创建多达20个GSI,并可以通过请求进一步提高此软限制https://aws.amazon.com/about-aws/whats-new/2018/12/amazon-dynamodb-increases-the-number-of-global-secondary-indexes-and-projected-index-attributes-you-can-create-per-table/
  2. GSI将花费您额外的钱,因为您需要将Provisioned Throughput分配给它
  3. GSI最终是一致的,这意味着DynamoDB不能保证与表的哈希键相关的数据被写入DB的那一刻,数据的GSI哈希键立即可用于查询。DynamoDB文档指出,这通常是即时的,但可能需要几秒钟的时间才能获得GSI哈希密钥
  4. 不能在GSI上执行GetItem以获得基于其Hash Key/Hash Key+Range Key的项目。您只能使用返回ListQuery

这个答案可能有一些用处,但你对实现它的两种方法是正确的

假设您使用id作为哈希键,那么为了只使用时间戳检索项目,您需要一个全局辅助索引。您仍然可以将timestamp作为范围键,这将非常有用,因为DynamoDB将使用它按id对查询结果进行排序。

使用全局辅助索引的主要缺点是需要在表上提供额外的吞吐量。

我也有类似的兴趣,并考虑在时间戳的一部分(例如,天或小时)上创建一个二级索引作为HASH,Id作为RANGE,以允许针对特定时间片进行查询,但这将强制时间片内的所有记录都在索引的同一分区中。

为了能够查询最近的数据和历史数据,亚马逊建议采用多表设计方法-请参阅https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-time-series.html.

相关内容

  • 没有找到相关文章

最新更新