如何查看、浏览和编辑 DynamoDB 数据
你对一张 DynamoDB 表的每次"查看"或"更改"都映射到一小组
API 操作之一——GetItem、Query、Scan、PutItem、UpdateItem、DeleteItem。
底层没有关系型表查看器:"浏览一张表"字面上就是一次
Scan,而"编辑一行"就是针对主键的一次 UpdateItem。知道每次点击
映射到哪个操作,是廉价读取与你无意中运行的整表
扫描之间的区别。
DynoTable 正是这些操作之上的一个 GUI——它在操作触及线缆之前, 向你展示你将要运行哪一个,以及成本。
如何浏览 DynamoDB 表
打开一张表"看看里面有什么"是一次 Scan——它读取表
或索引中的每个项(AWS:
"Amazon DynamoDB 中的 Scan 操作读取表或辅助索引中的每个项。")。
对小表没问题;对大表它就是
query vs scan 中讲的经典成本陷阱。
单次 Scan 最多返回 1 MB 数据,然后给你一个 LastEvaluatedKey 来
获取下一页——所以"浏览整张表"其实是一个分页循环
(AWS:
"单次 Scan 请求最多可检索 1 MB 数据",且
"Scan 响应中的 LastEvaluatedKey 应作为下一次 Scan 请求的
ExclusiveStartKey")。参见
分页了解游标如何工作,以及为什么这里不存在
偏移式的页码。
如何过滤 / 扫描 DynamoDB 数据
陷阱:过滤表达式不会为你省下一次扫描。DynamoDB 在读取 完成之后才应用过滤器,所以你为扫描的每个项付费——而不仅是你 保留的行。
过滤表达式在
Scan完成之后、结果返回之前 应用。因此,无论是否存在过滤表达式,Scan都消耗相同 数量的读容量。 — AWS Scan 文档
响应让这一点可见:ScannedCount 是"在应用任何 ScanFilter
之前所评估的项数",而 Count 是经过过滤器幸存下来的
(AWS)。
高 ScannedCount 配极小的 Count 正是低效扫描的特征。
如何查询 DynamoDB 表
Query 是廉价、精准的读取——但它需要一个分区键。根据
AWS:
"你必须提供分区键属性的名称和该属性的单个值。Query
返回具有该分区键值的所有项。可选地,
你可以提供一个排序键属性并使用比较运算符来细化搜索结果。"
所以一次 Query 只读取一个分区键下的项,可选地由
排序键条件缩小范围——从不读取整张表。没有分区键,就没有 Query:你
又回到了 Scan。这个选择是 DynamoDB 中最重要的单个
成本决策;完整剖析见 query vs scan。
要组装 KeyConditionExpression / FilterExpression 而不手写
占位符语法,用
DynamoDB 表达式构建器——它发出
API 期望的确切名称/值映射。
如何编辑 DynamoDB 中的一个项
编辑一个项是针对其完整主键的一次 UpdateItem。你不会
重写整个项——你提供一个更新表达式,只命名你正在
更改的属性:
UpdateItem
Key: { "PK": "USER#42", "SK": "PROFILE" }
UpdateExpression: SET email = :e, updatedAt = :t两个绊倒人的事实,都来自 AWS 项文档:
- 你必须指定整个主键,而非它的一部分。 在 复合键表上那是分区键和排序键。你无法通过一个 任意属性来"编辑一行"——那需要先扫描找到键。
UpdateItem是一次 upsert。 "如果不存在具有指定键的项,UpdateItem会创建一个新项。否则,它会修改一个现有项的 属性。" 键中的一个拼写错误会静默创建一个新项而非 报错。
如何删除一个项
一次 DeleteItem,同样以完整主键为键:
"DeleteItem 删除具有指定键的项"
(AWS)。
与编辑同一条规则——你需要整个键,所以删除"所有 status =
'open' 的行"不是一次调用;你要扫描/查询找到这些键,然后逐个删除。
BatchWriteItem 打包最多 25 个 put/delete 请求
(AWS:
"BatchWriteItem 操作最多可包含 25 个独立的 PutItem 和
DeleteItem 请求"),但每个仍然针对一个键——没有 DELETE … WHERE。
如何查看嵌套 / JSON 数据
DynamoDB 项以一种带类型标签的线缆格式(DynamoDB-JSON)存储,其中每个
值都携带一个一或两字母的类型描述符(S、N、M、L、SS……——
完整的描述符列表在
AWS 数据类型文档中)。
普通 JSON 没有集合类型,所以一个数组往返时会变成列表(L),从不
是字符串集合(SS)——这是真正的转换限制,而非显示 bug。完整的类型映射在
DynamoDB 数据类型中;要把一个 DynamoDB-JSON 数据块转换成普通
JSON 再转回去,用 DynamoDB JSON 转换器。
超越浏览与编辑:DynamoDB 做不到的查询
Scan/Query/UpdateItem 涵盖查看和编辑,但它们无法分析——
DynamoDB 没有 JOIN、GROUP BY 或 COUNT/SUM 这样的聚合函数,且
PartiQL 也没有添加它们:它的 SELECT 语法
只是 SELECT … FROM table [WHERE …] [ORDER BY …],没有连接或分组子句
(AWS PartiQL SELECT 参考),
所以每条语句映射到单个 Get/Query/Scan/Put/Update/Delete。DynoTable 的 SQL
Workbench 通过 DynamoDB 真正的查询运行时把你的表物化并
在其上运行 SQL 来填补那个缺口——在 DynamoDB 的访问模式规则内的 SQL——
但对于日常的浏览与编辑,上面的操作就是整个工具箱。
常见问题
如何在不用 AWS 控制台的情况下查看 DynamoDB 数据?
用一个发出同样 Scan/Query 调用的桌面 GUI。AWS 控制台
通过分页扫描浏览表;像 DynoTable 这样的专用客户端做同样的事,但
会显示消耗的容量和你正在运行的操作。
如何编辑一个 DynamoDB 项?
针对项的完整主键发出一次 UpdateItem,并用一个只命名你正在
更改的属性的 SET 更新表达式。在 GUI 中,内联编辑那个
单元格——它会为你编译成那次 UpdateItem。
为什么过滤仍然花费一次整表扫描? 因为 DynamoDB 在扫描读取这些项之后才应用过滤器。被过滤掉的 项仍被读取并计量。要降低成本,按一个分区键(或一个 GSI)查询,而不是扫描。
我能一次更新很多项吗?
不能在一次调用中。UpdateItem/DeleteItem 各自针对单个主键;没有
UPDATE … WHERE。你要扫描/查询来收集这些键,然后逐个写入(每个
BatchWriteItem 最多 25 个)。
我能用同样的方式浏览一张 DynamoDB Local 表吗? 能——把同一个 GUI 指向本地端点。参见 DynamoDB Local。
想浏览、过滤和内联编辑 DynamoDB 表——并运行 PartiQL 做不到的 SQL?下载 DynoTable。