DynamoDB-从分区键列表中获取对象的最有效/最便宜的方法?

时间:2019-05-09 21:26:20

标签: nosql amazon-dynamodb serverless dynamodb-queries

比方说,我的客户有一个PK列表:

PKs = [uuid1, uuid2, uuid3, uuid4, ...]

我需要获取具有这些对应PK的对象。

我可以想到3种方式:

交易

使用TransactGetItems,我一次可以获取10个项目,因此我将逐个获取每个项目,直到全部获取为止

批量获取商品

与交易相同,但不是交易性的,我一次可以提取25个项目。

带有过滤器的查询(可能比较混乱)

相反,我可以拥有一个具有不变属性的GSI作为“分区键”,并将原始的“分区键”设置为属性,然后我可以在条件表达式中链接一堆“ OR”。

例如(boto3):

table.query(
    KeyConditionExpression=Key('gsi1_pk').eq('metadata'),
    #Bunch of ORs togheter
    FilterExpression=Attr('pk').eq('uuid1') | Attr('pk').eq('uuid2') ...
    Index='GSI1-Index1'
)

现在,根据定价页面:

  

DynamoDB为每个高度一致的数据库收取一个读取请求单元   读取(最大4 KB),每个事务读取有两个读取请求单元,   和每个最终一致性读取的一半读取请求单元

我不确定读取的是什么1,它是否考虑返回的每个对象或扫描的每个对象?每个不同的请求至少是1个RCU,还是求和,直到达到1个RCU?

以下3个示例中,哪个示例是DynamoDB定价系统之后最便宜的?还有另一种方法吗?

计算的奖励积分。

1 个答案:

答案 0 :(得分:1)

好的交易应该是您的最后选择,因为这与交易逻辑无关。

BatchGetItems每个项目消耗1RCU,但是,Query消耗RCU,具体取决于查询的项目总大小(不返回!)。如果要查询一个表并返回100个项目,但每个项目的大小为1kb(不带过滤器),则将为400kb,因此消耗了10个RCU(计算可能是错误的,写得很快,但您明白了)。因此,查询在很多情况下都比您便宜得多。就您而言,您只需要扫描整个表,因为据我所知,HASH是静态的。

您最好的选择是BatchGetItems,但是这里有一个很大的然而 ...

您最终如何只拥有想要的ID?这不是NoSQL模式。您可能要做的是规范化非DynamoDB的数据。您应该对其进行脱模,以便在可以获取这些ID列表的位置获得其相关属性。如果您查询某些内容并获得ID,则对ID的另一个请求只是说它的NORMALIZED和DynamoDB不合适。

我建议您重新考虑数据设计和访问模式。