假设我有一个带有 id
和 timestamp
属性的用户表。我希望能够查询这两个参数。如果我对文档的理解正确,有两种方法可以使用 DynamoDB 执行此操作:
- 使用
id
作为散列,使用timestamp
作为范围定义散列+范围主键。 - 使用
id
定义一个仅哈希主键,并使用timestamp
定义一个全局二级索引。
每种方法的优缺点是什么?
最佳答案
Define a hash+range primary key using id as the hash and timestamp as the range.
通过制作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
您可以执行这些操作:
-
GetItem
根据id
获取单个项目(哈希键)+timestamp
(范围键)组合 -
Query
获取等于id
的所有项目的列表(哈希键)
如果这不是您想要的,请在 id
上散列 + 范围和 timestamp
分别不是您要找的。p>
Define a hash-only primary key using id and define a global secondary index using timestamp.
在 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
然后申请GSI
仅哈希 timestamp
,您将能够查询 ids
的列表对于特定的 timestamp
.
这种方法的好处是,它绝对是适合您的用例的正确解决方案。 #1 是范围键的误用(除非您打算在应用程序级别确保 id
不重复,这可能是个坏主意)。
使用 GSI
的缺点是:
最多只能有 5 个DynamoDB 2019 年 12 月更新 - 您现在可以创建多达 20 个GSI
每个表,因此请明智地选择您想要索引的内容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/-
GSI
将花费您额外的钱,因为您需要为其分配预配置吞吐量。 -
GSI
是最终一致的,这意味着 DynamoDB 不保证与表的哈希键关联的数据写入数据库时,数据的GSI
哈希键立即可用于查询。 DynamoDB 文档指出这通常是即时的,但对于GSI
可能需要几秒钟的时间。哈希键可用。 - 您无法执行
GetItem
在GSI
上根据其Hash Key
获取项目/Hash Key
+Range Key
.您被限制使用Query
返回List
关于database - DynamoDB : range vs. 全局二级索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23276462/