大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Query 与 Scan
Query 按主键或 GSI 键高效读取;Scan 全表遍历,成本高、应尽量避免。DynamoDB 没有 SQL 式任意 WHERE。
学习目标
- 掌握 Query 的 KeyCondition 与 FilterExpression
- 理解分页
LastEvaluatedKey与Limit - 知道何时 Scan 可接受、如何控成本
核心内容
Query(推荐)
aws dynamodb query \
--table-name UserProgress \
--key-condition-expression "PK = :pk AND begins_with(SK, :prefix)" \
--expression-attribute-values '{
":pk": {"S": "USER#u_1001"},
":prefix": {"S": "LESSON#"}
}' \
--scan-index-forward false \
--limit 10
| 参数 | 作用 |
|---|---|
| KeyConditionExpression | 必填,仅主键/GSI 键条件 |
| FilterExpression | 可选,键条件后再过滤非键属性 |
| ScanIndexForward | false = SK 降序 |
| ExclusiveStartKey | 分页起点(上一页 LastEvaluatedKey) |
Java Query 分页
QueryRequest req = QueryRequest.builder()
.tableName("UserProgress")
.keyConditionExpression("PK = :pk")
.expressionAttributeValues(Map.of(
":pk", AttributeValue.builder().s("USER#u_1001").build()))
.limit(20)
.build();
QueryResponse resp = client.query(req);
// 若 resp.lastEvaluatedKey() 非空,放入 exclusiveStartKey 继续
Scan(慎用)
aws dynamodb scan \
--table-name UserProgress \
--filter-expression "#a = :complete" \
--expression-attribute-names '{"#a":"action"}' \
--expression-attribute-values '{":complete":{"S":"complete"}}'
Scan 读 每一分区每一 Item,再应用 Filter——大表极贵。报表/analytics 导出到 S3 + Athena,或同步到 postgresql-essentials 只读副本。
与 MongoDB / SQL 对照
| 操作 | DynamoDB | MongoDB | MySQL |
|---|---|---|---|
| 主键查 | GetItem | findOne({_id}) | PK lookup |
| 索引范围 | Query + GSI | find({field}) | WHERE + INDEX |
| 全表 | Scan(贵) | find({}) | SELECT *(可控) |
cf_track 列表查询在 MySQL 用 ORDER BY + 索引;DynamoDB 需 预设计 SK 排序 或 GSI。
练习
- Query 某用户全部 LESSON# 前缀进度,SK 降序取 Top 5
- 实现分页:循环 Query 直到 LastEvaluatedKey 为空
- 说明 FilterExpression 为何不减少 RCU 消耗
小结
Query 按键读、Scan 全表扫;生产路径 Query + GSI,Scan 仅小表或离线。 下一课 DynamoDB Streams。