以示例讲解 DynamoDB 的 PartiQL
是 DynamoDB 的一种兼容 SQL 的查询语言。对于临时性的工作,它比原始 API 更友好——但它运行在同一个引擎之上,所以熟悉的语法之下,同样的键规则(以及同样的开销)依旧成立。
如何为 DynamoDB 编写 PartiQL 查询?
PartiQL 给了 DynamoDB 四种类 SQL 的语句——SELECT、INSERT、UPDATE 和 DELETE——通过 ExecuteStatement 运行。每一条在底层都会编译成一个原生操作,所以对 做筛选仍然是一次 Query,而省略它则变成一次全表 Scan。写入仍然按 只针对一个项;没有关系型的 JOIN、GROUP BY 或聚合。
SELECT
SELECT * FROM "AppData"
WHERE "PK" = 'CUSTOMER#42' AND begins_with("SK", 'ORDER#')对 做筛选,这就是一次 Query。省略分区键,PartiQL 就会悄悄运行一次全表 Scan——同样的坑,只不过藏在 SELECT * 后面。
INSERT
INSERT INTO "AppData" VALUE {'PK': 'CUSTOMER#42', 'SK': 'PROFILE', 'plan': 'pro'}UPDATE
UPDATE "AppData" SET "plan" = 'enterprise'
WHERE "PK" = 'CUSTOMER#42' AND "SK" = 'PROFILE'DELETE
DELETE FROM "AppData"
WHERE "PK" = 'CUSTOMER#42' AND "SK" = 'ORDER#2026-001'查询索引
在 FROM 子句中使用索引名:
SELECT * FROM "AppData"."GSI1" WHERE "GSI1PK" = 'STATUS#OPEN'WHERE 也支持 IN、contains() 和 begins_with():
SELECT * FROM "AppData"
WHERE "PK" = 'CUSTOMER#42' AND "SK" IN ['ORDER#1', 'ORDER#2']参数化语句
用 ? 占位符代替把值内联进去——这样能绕开引号/注入问题,并让 SDK 帮你完成类型的 marshal:
SELECT * FROM "AppData" WHERE "PK" = ? AND begins_with("SK", ?)向 ExecuteStatement 传入 Parameters: [{ S: 'CUSTOMER#42' }, { S: 'ORDER#' }]。
批处理与事务
BatchExecuteStatement—— 一次往返最多 25 条语句。更快,但没有跨项原子性(每条各自成功或失败)。ExecuteTransaction—— 最多 100 条语句,全有或全无。当多个写入必须一起提交时用它。
PartiQL 的坑
PartiQL 看起来 像 SQL,但运行在 DynamoDB 引擎上,所以 SQL 习惯会适得其反:
- 单条
UPDATE/DELETE必须按完整的 只针对一个项——没有UPDATE … WHERE status = 'x'式的批量更新(改用批处理循环)。 - 没有
JOIN、没有GROUP BY、没有聚合(COUNT/SUM/AVG)。参见 PartiQL 与 SQL。 - 省略分区键会把任何
SELECT变成一次全表 Scan——唯一的边界就是你的账单。
当你确实需要一个 JOIN、一个 GROUP BY 或一个聚合时,DynoTable 的 SQL Workbench 会在你已拉取的行上于客户端运行它们——那正是 PartiQL 说不出口的 SQL,就在 DynamoDB 的访问模式规则之内。
PartiQL 并不改变底层的 数据类型——值仍然以 DynamoDB-JSON 的形式在网络上传输,你可以用 转换器 来查看它。
试用 DynoTable,用能感知 schema 的自动补全来运行 PartiQL 语句,并在可排序的表视图中浏览结果。