程式碼可以直接抹除重來,資料不行——它必須被保留、遷移,往往比建立它的應用程式更長壽,可以說是整個系統最有價值的部分。所以資料庫變更要有一套機制,讓 schema 或內容的改動在風險最小的前提下完成,且能在部署失敗時安全回滾。核心手段就是:把遷移自動化、腳本化、版本化。
🧠 Intuition
TIP
所有資料庫變更(初始化、遷移)都應被腳本化並存入版本控制,且同一套腳本服務每一個環境:開發者建本地庫、SIT 環境升級、正式環境遷移。目標是——部署到任一環境時,資料庫 schema 都能與對應版本的應用程式相匹配。
- 為資料庫加版本號:庫中建一張表記錄當前版本,每次變更寫兩支腳本——前滾(roll-forward,x → x+1)與回滾(roll-back,x+1 → x);應用程式的設定記錄它需要的資料庫版本。
- 部署時工具(如 DbDeploy)比對當前版本與目標版本,自動依序執行:前滾由舊到新、回滾由新到舊(回滾腳本常以
--//@UNDO標記分隔)。 - 這樣達成兩件事:部署自動化(不必操心目標環境當前狀態)、解耦 DB 與應用變更(DBA 可獨立把遷移簽入版控,不會在開發者更新程式碼前被意外觸發)。
- 若前滾會刪資料,回滾腳本應先把資料(含主鍵)複製到暫存表,才能還原並重建約束。
⚖️ Tradeoffs
回滾時不丟資料 — 幾種策略各有代價
- 可直接回滾:schema 變更不遺失資料(正規化/反正規化、欄位搬移),或被刪資料僅新版使用且可接受遺失。
- 需特殊處理:回滾要刪掉不可遺失的新交易資料時——用快取與重播(cache & replay):升級後記錄每筆交易(UI 事件、訊息攔截或交易日誌),回滾後重放。
- 藍綠部署(Blue-Green):發布前備份 Blue 庫、還原到 Green 並遷移、切流量到 Green;要回滾就切回 Blue,Blue 資料完整無損。代價:資料量過大時備份還原太久,兩環境只能共用同一庫、發布時切連線。
把遷移與部署解耦 — 前向相容才是日常預設
- 不必每次發布都遷移。需要遷移時先部署一個過渡版本(transitional version),讓它同時相容當前與新版 schema;確認新版應用穩定後再執行遷移;下一個版本才只需相容新 schema。
- 好處:遷移前能充分觀察新版行為;即使遷移涉及不可逆的 schema 變更,也能在升級前確認不需回滾。
- 前向相容(forward compatibility)——舊版應用能跑在新版 schema 上——是日常變更的預設策略;最佳實踐是讓變更盡量加法性(additive):新增表或欄位,而非改動現有結構。也可用抽象層(stored procedure / view,即 branch by abstraction)在不影響應用的前提下改底層物件。
- 多應用共用一個庫時(不建議但常見),變更會有連鎖效應:在 SIT 測試、維護一份「哪個應用用哪些物件」的登記簿,並讓應用同時相容多版本,使遷移能獨立於部署進行。
🔑 Takeaways
- 資料是系統最有價值、最長壽的部分:腳本化 + 版本控制 + 自動遷移(DbDeploy),每次變更配一支前滾與一支回滾腳本。
- 回滾別丟資料:可直接回滾的先分清楚,否則用 cache & replay 或藍綠部署(Blue 保完整);資料量太大時藍綠退化為共用庫切連線。
- 把遷移與部署解耦:過渡版本同時相容新舊 schema、變更盡量加法性、優先前向相容——這也是 canary / blue-green 能安全回滾的前提。
No notes yet — jot your takeaways or Q&A here.