使用DocumentClient时,如何通过主键数组从DynamoDB取数据?选Scan还是Query?
关于DynamoDB DocumentClient处理主键数组的问题解答
一、选Scan还是Query?答案很明确
别考虑Scan——优先用批量主键查询(BatchGetItem)或者针对单个主键循环调用Query,原因如下:
Scan是全表扫描,会遍历表中每一条数据,表越大性能越差,还会浪费大量读取容量单位(RCU),成本高到肉疼。Query是针对主键的精准查询,只扫描匹配分区键的分区,效率拉满,RCU消耗也低。如果是多个主键,BatchGetItem比循环单个Query更高效,因为它能一次请求搞定多个主键,减少网络来回折腾的次数。
二、如何通过主键数组获取数据?
用DocumentClient的话,分两种常见场景给你代码示例:
场景1:单分区键的主键数组
假设你的表叫UserTable,分区键是userId(字符串类型),现在有一堆用户ID数组["user_001", "user_002", "user_003"],用BatchGetItem批量获取:
const AWS = require('aws-sdk'); const documentClient = new AWS.DynamoDB.DocumentClient(); async function fetchItemsByPrimaryKeys(tableName, primaryKeyList) { const requestParams = { RequestItems: { [tableName]: { Keys: primaryKeyList.map(key => ({ userId: key })) // 这里的key就是你主键数组里的每个分区键值 } } }; try { const response = await documentClient.batchGet(requestParams).promise(); // 成功获取到的数据在Responses[tableName]里 return response.Responses[tableName]; } catch (error) { console.error('批量获取数据出错:', error); throw error; } } // 调用示例 const targetUserIds = ["user_001", "user_002", "user_003"]; fetchItemsByPrimaryKeys('UserTable', targetUserIds) .then(items => console.log('拿到的数据:', items)) .catch(err => console.error('出问题了:', err));
场景2:复合主键(分区键+排序键)的数组
如果你的表是复合主键,比如分区键userId+排序键orderId,主键数组是[{userId: "user_001", orderId: "order_1001"}, {userId: "user_002", orderId: "order_1002"}],代码只需要调整Keys部分:
const compositePrimaryKeys = [ { userId: "user_001", orderId: "order_1001" }, { userId: "user_002", orderId: "order_1002" } ]; const requestParams = { RequestItems: { 'OrderTable': { Keys: compositePrimaryKeys } } }; // 后续调用逻辑和上面一致
几个要注意的点
BatchGetItem一次最多处理100个主键,或者总数据量不超过16MB,哪个先到算哪个。如果你的主键数组超过100个,记得分批处理。- 如果某些主键对应的数据不存在,
BatchGetItem不会报错,只会返回存在的数据;如果有未处理的键(比如超过限制),会出现在UnprocessedKeys里,你可以重试这些键。 - 确保你的IAM角色有
dynamodb:BatchGetItem权限(如果用循环Query的话,需要dynamodb:Query权限)。
内容的提问来源于stack exchange,提问作者Dmitry Grinko
相关产品推荐
相关产品推荐

