比方说,我的客户有一个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定价系统之后最便宜的?还有另一种方法吗?
计算的奖励积分。
答案 0 :(得分:1)
好的交易应该是您的最后选择,因为这与交易逻辑无关。
BatchGetItems
每个项目消耗1RCU,但是,Query
消耗RCU,具体取决于查询的项目总大小(不返回!)。如果要查询一个表并返回100个项目,但每个项目的大小为1kb(不带过滤器),则将为400kb,因此消耗了10个RCU(计算可能是错误的,写得很快,但您明白了)。因此,查询在很多情况下都比您便宜得多。就您而言,您只需要扫描整个表,因为据我所知,HASH是静态的。
您最好的选择是BatchGetItems
,但是这里有一个很大的然而 ...
您最终如何只拥有想要的ID?这不是NoSQL模式。您可能要做的是规范化非DynamoDB的数据。您应该对其进行脱模,以便在可以获取这些ID列表的位置获得其相关属性。如果您查询某些内容并获得ID,则对ID的另一个请求只是说它的NORMALIZED和DynamoDB不合适。
我建议您重新考虑数据设计和访问模式。