DynamoDB - 从分区键列表中获取对象的大多数 efficient/cheap 方式?

DynamoDB - Most efficient/cheap way of getting a objects from a list of partition keys?

假设我的客户端有一个 PK 列表:

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

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

我可以想到 3 种方法:

交易

使用 TransactGetItems,我可以一次获取 10 个项目,所以我会单独获取每个项目,直到我全部获取它们

批量获取物品

与事务相同,但不是事务性的,我一次可以获取 25 个项目。

带过滤器的查询(可能很乱)

我可以改为使用具有不可变属性的 GSI 作为分区键,并将原始分区键设置为属性,然后我可以在条件表达式中链接一堆 "ORs"。

例如 (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 charges one read request unit for each strongly consistent read (up to 4 KB), two read request units for each transactional read, and one-half read request unit for each eventually consistent read

我不确定 1 read 是什么,它考虑了返回的每个对象还是扫描的每个对象?每个不同的请求至少是 1 个 RCU 还是它们加起来直到达到 1 个 RCU?

以上 3 个示例中的哪一个是遵循 DynamoDB 定价系统的最便宜的?还有其他方法吗?

计算加分。

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

BatchGetItems 每个项目消耗 1RCU,但是,Query 根据项目的总大小消耗 RCU queried(不是 return编!!)。如果您要查询 table 和 return 100 个项目,但每个项目的大小为 1kb(没有过滤器),它将是 400kb,因此消耗了 10 个 RCU(计算可能有误,写入速度非常快,但是您得到这个想法)。所以在很多情况下查询要便宜得多,除了你的。在您的情况下,您只需扫描整个 table,因为据我所知,HASH 是静态的。

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

你怎么最终只有你想要的 ID?这不是 NoSQL 模式。您可能做的是规范化不适用于 DynamoDB 的数据。您应该对其进行去规范化,以便在可以获得这些 ID 列表的地方也可以获得它们的相关属性。如果您查询某些内容并获取 ID,那么对 ID 的另一个请求只是说它的 NORMALIZED 和 DynamoDB 不适合它。

我会建议你 re-consider 你的数据设计和访问模式。