如何檢視、瀏覽與編輯 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 Expression Builder — 它吐出
API 期待的確切 names/values 對應。
如何在 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 沒有 set 型別,所以一個陣列往返時會變成一個 list(L),永遠不是字串
set(SS) — 這是一個真實的轉換限制,不是顯示錯誤。完整的型別對應在
DynamoDB 資料型別中;要把一個 DynamoDB-JSON blob 轉成純
JSON 再轉回來,請用 DynamoDB JSON 轉換器。
超越瀏覽與編輯:DynamoDB 做不到的查詢
Scan/Query/UpdateItem 涵蓋檢視與編輯,但它們無法分析 —
DynamoDB 沒有 JOIN、GROUP BY,也沒有像 COUNT/SUM 的彙總函式,而
PartiQL 也沒有加上它們:它的 SELECT 文法
就是 SELECT … FROM table [WHERE …] [ORDER BY …],沒有 join 或分組子句
(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。