DynamoDB 支援外鍵嗎?
不支援。DynamoDB 沒有外鍵、參考完整性約束或連鎖刪除 — 作為一個 NoSQL 資料庫,它從不強制項目或表格之間的關聯。你得自己建模那些關聯:把相關資料反正規化到同一個項目裡,或以單一表格設計把相關項目共置在同一個 partition key 底下。若要看見並走訪那些建模出來的關聯,DynoTable 的 Smart Table 能在畫布上把兩張表格之間的關聯畫出來,並瀏覽 join 後的資料列。
為什麼沒有外鍵
外鍵的存在是為了支援 join,並在正規化的表格之間強制完整性。DynamoDB 刻意省略了 JOIN 運算子(AWS 建議改為反正規化),所以外鍵約束會去管制一段查詢模型根本不會利用的關聯。沒有什麼阻止你把另一個項目的鍵存成一個屬性 — DynamoDB 只是不會驗證它,也不會為它做連鎖處理。
關聯改以何種方式建模
- 內嵌 — 小型、有界的子資料以 list 或 map 的形式住在父項目裡面。
- 共置 — 父項目與子項目共用一個 partition key、搭配不同的 sort key,於是一次
Query就回傳整段關聯;這正是單一表格設計的核心。 - 複製 — 把每個存取模式所需的欄位複製到需要它們的項目上,用寫入時的維護成本換取單一請求的讀取。
當完整性真的要緊時如何強制它
對於那些你原本會靠約束來處理的情況,DynamoDB 給了你一些構件:條件運算式能依被寫入項目的狀態來防護一次寫入,而交易的 ConditionCheck 能在同一個全有或全無的操作裡,驗證一個不同的項目(例如父項目)是否存在。連鎖刪除則變成明確的應用程式邏輯,或一段由 Streams 驅動的清理。
實際跑起來是什麼樣子
我們在 pk = "CUSTOMER#1" 底下放了一個 PROFILE 項目與兩個 ORDER# 項目,刪掉那個 profile,然後再查詢一次那個分割區:
Count: 2
[{"sk":{"S":"ORDER#1"},"pk":{"S":"CUSTOMER#1"}},
{"sk":{"S":"ORDER#2"},"pk":{"S":"CUSTOMER#1"}}]刪除回報成功。兩個孤兒,沒有警告,也沒有錯誤可以攔。在 PostgreSQL 裡,同一個刪除會失敗、會連鎖,或把子項目的參考設成 null,取決於你宣告了哪一種約束。
接著是最接近的替代品:一個在寫入第三筆訂單之前先對父項目做條件檢查的 TransactWriteItems。
TransactionCanceledException: Transaction cancelled, please refer cancellation
reasons for specific reasons [ConditionalCheckFailed, None]
CancellationReasons: [
{"Code":"ConditionalCheckFailed","Message":"The conditional request failed."},
{"Code":"None"}
]陣列的位置對應你 TransactItems 的位置,所以 [ConditionalCheckFailed, None] 的意思是動作 0(父項目檢查)失敗、動作 1(子項目寫入)沒問題。只有一個防護時這讀起來很直白;有八個動作時,那個陣列就是你唯一能查出是哪一個壞掉的方法。
它也會計費。一次交易式寫入每個項目消耗兩個寫入單位,而 AWS 明講 "this capacity is consumed even when the transaction is canceled"。每一次被拒絕的寫入,花費都跟被接受的一樣。
深入了解
從單一表格設計開始,在運算式建構器裡組出那些防護條件,然後下載 DynoTable 以視覺化方式瀏覽那些關聯 — 它的 Smart Table 會在畫布上把父表格與子表格 join 起來,讓你在一個檢視中看到整個項目集合。
參考資料
- What is Amazon DynamoDB? — Amazon DynamoDB Developer Guide
- Amazon DynamoDB Transactions: How it works — Amazon DynamoDB Developer Guide
- Best practices for NoSQL design — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations — Amazon DynamoDB Developer Guide
最後驗證於 2026-07-13,對照上方連結的官方 AWS 文件。
孤兒子項目的查詢結果與那段取消輸出,是於 2026-07-28 在 Node v24.18.0 上,以 @aws-sdk/client-dynamodb 3.1095.0 對照 DynamoDB Local 3.3.0 重現的。