觀點 · 資訊分享

Aurora DSQL 終於支援外鍵:資料表之間的關聯交給資料庫把關,程式少寫一層檢查

AWS 的分散式資料庫 Aurora DSQL 開始支援外鍵限制,新舊資料表都能加。訂單指到不存在的商品這種髒資料,資料庫會直接擋下來,但寫入衝突時要記得重試。

發布
2026-08-27
篇幅
約 4 分鐘 · 1,825 字
結構
7 節 + 4 題常見問題
標籤
#AWS#Aurora DSQL#PostgreSQL#資料庫
Aurora DSQL 終於支援外鍵:資料表之間的關聯交給資料庫把關,程式少寫一層檢查

一句話看懂:AWS 的分散式資料庫 Aurora DSQL 開始支援外鍵,資料表之間的關聯可以交給資料庫把關,不用再全靠程式碼自己檢查。

Aurora DSQL 開始支援外鍵資訊圖卡:訂單指到不存在的商品?現在資料庫會直接拒絕這筆寫入

先用白話講:外鍵是什麼?

想像一間餐廳的點餐單。每張點餐單上都會寫「點了幾號餐」,而菜單上一定要真的有這個號碼,不然廚房會一頭霧水。

外鍵(Foreign Key)就是資料庫裡的這條規則:訂單表裡的「商品編號」,必須在商品表裡找得到。有了它,資料庫會主動擋下兩種錯誤:

  • 新增一張訂單,卻指到根本不存在的商品
  • 把商品刪掉,卻還有訂單指著它(這種被遺留的資料叫「孤兒資料」)

一般的 PostgreSQL、MySQL 早就有外鍵,但 AWS 的 Aurora DSQL 是另一種設計:它把資料分散在多個區域同時讀寫,在這次更新之前並不提供外鍵,開發者只能在程式裡自己檢查。

發生什麼事

AWS 在 8 月 27 日宣布,Aurora DSQL 現在可以替新建和既有的資料表加上外鍵限制,所有提供 DSQL 的區域都能用。

  • 支援 5 種「被指向的資料刪除或修改時怎麼辦」的動作:NO ACTION、RESTRICT、CASCADE、SET NULL、SET DEFAULT
  • 支援 2 種比對方式:MATCH FULL 和 MATCH SIMPLE(預設)
  • 也支援可延後到交易結束才檢查的外鍵(DEFERRABLE)

跟一般資料庫有什麼不一樣?

一般資料庫檢查外鍵時會「上鎖」,別人要改同一筆資料就得排隊。DSQL 不這樣做,而是分兩步:

步驟 做法 白話
交易進行中 用交易開始那一刻的快照確認關聯成立 先照當下的菜單核對
提交時 檢查期間有沒有人改到被指向的資料 送單前再確認菜單沒被改

好處是大家可以同時寫入、不用排隊;代價是衝突不會等待,而是直接失敗。例如 A 刪掉商品、B 同時新增指向它的訂單,先提交的 A 會成功,B 提交時就會收到錯誤。

給開發者的技術細節

語法和 PostgreSQL 相同,可以寫在欄位後面,也可以寫成資料表限制:

CREATE TABLE orders (
  order_id   integer PRIMARY KEY,
  product_id integer REFERENCES products ON DELETE RESTRICT,
  quantity   integer
);
  • 沒寫被指向的欄位時,預設指向對方的主鍵
  • 衝突時會回 SQLSTATE 40001(序列化錯誤),一定要寫重試邏輯
  • 官方文件提醒:所有動到相關資料表的寫入都會多出讀取,加之前先壓測
  • 被大量參照的那一列,被參照的欄位最好不要常改;常變動的值放在其他欄位,就不會跟新增訂單互相衝突

我的看法

接案做系統時,資料表之間的關聯是最容易出包的地方:程式某條路徑忘了檢查,資料庫裡就多一筆孤兒資料,等到報表對不起來才發現。能把這層交給資料庫,是很實在的進步,也讓既有的 PostgreSQL 專案搬到 DSQL 少一個改寫的理由。

不過要記得 DSQL 的個性:它選擇「衝突就失敗」而不是「排隊等」。習慣傳統資料庫的人如果沒寫重試,流量一高就會看到一堆莫名其妙的錯誤。我的建議是先在重試機制完整的服務上加外鍵,再慢慢擴大。

名詞小辭典

  • 外鍵(Foreign Key):規定某個欄位的值,必須在另一張表裡找得到,用來維持資料之間的關聯正確。
  • 孤兒資料:指向的資料已經不存在,卻還留在資料庫裡的紀錄。
  • 交易(Transaction):一組要嘛全部成功、要嘛全部取消的資料庫操作。
  • 快照(Snapshot):交易開始那一刻整個資料庫的樣子,交易進行中都以它為準。

資料來源

常見問題

外鍵是什麼?一定要用嗎?
外鍵是資料表之間的「指向規則」,例如訂單裡的商品編號必須真的存在於商品表。不是一定要用,但用了之後,資料庫會幫你擋下會留下孤兒資料的寫入。
既有的 DSQL 資料表可以補加外鍵嗎?
可以。官方公告寫明新建和既有的資料表都能加上外鍵限制,所有提供 Aurora DSQL 的區域都能用。
加了外鍵會變慢嗎?
官方文件說,所有動到相關資料表的新增、修改、刪除都會多出讀取,用來確認關聯成立。建議加之前先用實際流量壓測,確認效能可以接受。
為什麼程式要加重試?
DSQL 遇到同時修改的衝突時,不會讓後來的交易排隊等待,而是在提交時直接回傳序列化錯誤(SQLSTATE 40001)。程式要能接住這個錯誤並重跑交易。
LINE