DynamoDB PartiQL vs SQL:什麼會失效
DynamoDB 的 PartiQL 最大的困惑來源——無論對人類還是 AI 助理都一樣——就是把它當成關聯式 SQL。它不是。PartiQL 是 一層架在 DynamoDB 既有操作之上的 SQL 相容介面,而不是一個能 join、grouping 或彙總的查詢引擎。那些熟悉的關鍵字,藏著一台底層截然不同的機器。
DynamoDB 的 PartiQL 和 SQL 有什麼不同?
PartiQL 借用了 SQL 的語法,但沒有借用它的引擎。在 DynamoDB 上,每個陳述式都對應到單一個原生操作——GetItem、Query、Scan、PutItem、UpdateItem 或 DeleteItem——所以沒有 JOIN、GROUP BY、子查詢或彙總。它讀起來像 SQL,但只能做那些索引鍵-值操作本來就做得到的事。
每個 PartiQL 陳述式都會編譯成 DynamoDB 的其中一個原生操作:
| 你寫的 | DynamoDB 執行的 |
|---|---|
SELECT … WHERE PK = … | GetItem 或 Query |
SELECT …(沒有 PK) | Scan(讀取 整張資料表) |
INSERT INTO … | PutItem |
UPDATE … WHERE PK=… AND SK=… | UpdateItem(一個項目) |
DELETE … WHERE PK=… AND SK=… | DeleteItem(一個項目) |
沒有任何規劃器能從兩張資料表讀取、建立雜湊 join,或把多列摺疊
成一個 COUNT。如果某個操作對應不到單一個 Get/Query/Scan/Put/Update/
Delete,PartiQL 就是無法表達它。故事就是這樣——底下所有內容
都是這一項事實的推論。
同樣的對應,畫成流程圖——WHERE 子句決定一個 SELECT 是
便宜的 Query 還是全表 Scan:
每個陳述式都解析成剛好一個原生操作——正是這種一對一的對應, 使 PartiQL 無法 join、grouping 或彙總。
差別在哪——逐項功能比較
只要 Workbench 那一欄標 是 而 PartiQL 標 否,那就是 DynoTable 的 SQL 補上的缺口。Workbench 透過 DynamoDB 真正的查詢執行環境把你的資料表具體化(materialize),並在其上執行真正的 SQL—— 在 DynamoDB 的存取模式規則之內的 SQL。
| 功能 | 標準 SQL | DynamoDB PartiQL | DynoTable Workbench |
|---|---|---|---|
JOIN … ON … | 是 | 否 | 是——INNER / LEFT(對 PK 或 GSI 分割區索引鍵) |
RIGHT / FULL / CROSS / 逗號 join | 是 | 否 | 否 |
| Self-join | 是 | 否 | 否(尚未支援) |
| 子查詢 / 衍生資料表 | 是 | 否 | 否 |
CTE(WITH …) | 是 | 否 | 否 |
UNION / INTERSECT / EXCEPT | 是 | 否 | 否 |
GROUP BY / HAVING | 是 | 否 | 是 |
彙總(COUNT/SUM/AVG/MIN/MAX) | 是 | 否 | 是 |
DISTINCT | 是 | 否 | 是 |
CASE / CAST | 是 | 否 | 是 |
| 視窗函式 | 是 | 否 | 否 |
ORDER BY | 是,任何欄位 | 部分——僅排序索引鍵(需要分割區索引鍵 WHERE) | 是,任何欄位 |
LIMIT | 是 | 沒有內嵌用法(改用請求的 limit 參數) | 是 |
LIKE | 是 | 否(改用 contains / begins_with) | 是 |
IS NULL / IS NOT NULL | 是 | 是(缺席的屬性是 MISSING,不是 NULL——用 IS MISSING) | 是 |
沒有 PK 的 SELECT * | 掃描 | 部分——悄悄的全表 Scan | 是(並有成本可見性) |
什麼會失效,以及為什麼
這些是 DynoTable 的 PartiQL 驗證器在查詢還沒送上線之前就會標出來的 失效——每一項都追溯到一個真實的 DynamoDB 限制。
- 沒有 的
SELECT *是一次隱藏的Scan。 PartiQL 不會報錯; 它就是把每個項目都讀出來、之後才過濾,這正是熟悉語法背後那個經典的 Query-vs-Scan 成本地雷。 UPDATE/DELETE需要完整的主索引鍵。 它們對應到單一項目的UpdateItem/DeleteItem,所以WHERE必須釘住分割區索引鍵(在 資料表上還要釘住排序索引鍵)。你無法用一個陳述式「更新所有 status = 'open' 的列」。- 雙引號是識別符,不是字串。 DynamoDB 的 PartiQL 在這裡遵循 SQL
標準:
"name"是欄位/資料表名稱,'name'是字串值。 用雙引號括住一個值是最常見的初學者錯誤——驗證器的 訊息就直接寫著 「Double quotes delimit identifiers in DynamoDB PartiQL, not strings. Use single quotes for string values.」 IN用中括號,不是小括號:WHERE pk IN ['a','b'],上限為 50 個 PK 值 / 100 個非索引鍵值。- 沒有
JOIN、沒有彙總。 沒有引擎能結合資料表或摺疊多列。 這是 單表設計 的取捨:你要 預先為你的存取模式建模,因為查詢層無法在事後重塑 資料。
為什麼 AI 助理會弄錯這件事
LLM 是在如汪洋般的關聯式 SQL 上訓練出來的,所以它們會自信滿滿地對
DynamoDB 吐出 JOIN、GROUP BY、LIKE、內嵌 LIMIT、以及雙引號的字串常值
——這些 DynamoDB 全都會拒絕。DynoTable 自家的 model-query 自動修正之所以存在,
正是因為便宜的模型可靠地會產出這些模式:它會剝掉
雙重跳脫的引號,把 LIKE '%x%' 改寫成 contains、IS NULL 改寫成
attribute_not_exists,並把內嵌的 LIMIT 提升到請求參數。如果你的
AI 產出的「PartiQL」讀起來像 Postgres,那就是破綻所在。
DynoTable 的 SQL Workbench:PartiQL 跑不了的查詢
當你真的需要 JOIN 或 GROUP BY 時,DynoTable 的 SQL Workbench 就是
答案。它會把每個 JOIN 的目標端驗證為一個分割區索引鍵,透過 DynamoDB 真正的
Query/Scan 執行環境把 join 後的列具體化,然後在其上執行單一個 SELECT
(彙總、GROUP BY、DISTINCT、CASE、CAST)——在 DynamoDB
存取模式規則之內的 SQL。
-- Runs in the DynoTable Workbench (NOT in PartiQL):
SELECT c.country, COUNT(*) AS orders, SUM(o.total) AS revenue
FROM orders o
INNER JOIN customers c ON o.customerId = c.PK
GROUP BY c.country
ORDER BY revenue DESC誠實的限制(Workbench 落實 DynamoDB 的存取模型,它不會 假裝自己是 Postgres):
- 僅支援
INNER JOIN與LEFT JOIN——ON的目標屬性必須是分割區索引鍵 或 GSI 分割區索引鍵。沒有RIGHT/FULL/CROSS/ 逗號 join。 - 尚未支援 self-join,沒有子查詢,沒有衍生資料表,沒有視窗函式。
- Join 與投影都在純量屬性上運作。
如果你只是需要為原生 API 組合條件與索引鍵運算式,
DynamoDB Expression Builder 會產生
正確的 FilterExpression / KeyConditionExpression,完全不需要 PartiQL 這層
介面。想把 PartiQL 用對,見完整示範的 PartiQL 範例;
想估算任何查詢的成本,用
項目大小計算器。要注意 PartiQL
從不改變傳輸格式——值依然以 DynamoDB-JSON 的形式傳送。
在挑選用戶端嗎?看看 Workbench 相較於
純粹的 DynamoDB GUI 或 Dynobase 落在哪裡。
常見問答
PartiQL 和 SQL 一樣嗎?
不一樣。PartiQL 是一種 SQL 相容的查詢語言,但在 DynamoDB 上它只暴露
對應到單一個 Get/Query/Scan/Put/Update/Delete 的操作。它沒有 join、
彙總、子查詢或 GROUP BY。
DynamoDB 的 PartiQL 能做 JOIN 嗎?
不能。DynamoDB 的 PartiQL 無法 join 資料表。DynoTable 的 SQL Workbench 可以透過
DynamoDB 真正的查詢執行環境把資料具體化,執行
INNER/LEFT JOIN(對分割區索引鍵或 GSI 分割區索引鍵)。
DynamoDB 的 PartiQL 支援 GROUP BY 或 COUNT 嗎?
不支援——DynamoDB 的 PartiQL 中沒有彙總或 GROUP BY。COUNT/SUM/AVG/GROUP BY/HAVING
的查詢請用 DynoTable 的 SQL Workbench。
為什麼我的 SELECT * 這麼貴?
WHERE 中沒有分割區索引鍵時,PartiQL 會跑一次全表 Scan,並在過濾套用之前就把
每個讀出來的項目都計費。加上一個分割區索引鍵述語,把它變成
一次 Query。
在 PartiQL 中我該用單引號還是雙引號?
字串值用單引號('CUSTOMER#42'),像資料表和屬性名稱這類識別符
用雙引號("AppData")。用雙引號括住一個值是最
常見的 PartiQL 錯誤。
準備好對 DynamoDB 執行真正的 SQL 了嗎?下載 DynoTable 並開啟一個 Workbench 分頁。