iT邦幫忙

0

🧩 從一次簡單的更新任務,看見Trigger、Audit、Flashback 與資料恢復的完整思考

  • 分享至 

  • xImage
  •  

最近在處理公司 EIP 資料庫時,我遇到一個看似「超簡單」的需求:
把員工資料表 ORG_EMPLOYEE 裡的 Email 網域,從舊的 @old.com.tw
改成新的 @new.com.tw

原本以為只是 UPDATE ... SET EMAIL = REPLACE(...) 的等級,沒想到一路從
Email 替換,延伸出:

  • 為什麼欄位不更新會報錯?
  • Trigger 什麼時候會把資料庫炸掉?
  • Audit Trigger 到底怎麼設計才不會變成技術債?
  • Flashback 和 Trigger 有什麼根本性的差別?
  • 如果哪天真的有人 DELETE、TRUNCATE、DROP 了表格,我們到底能不能救?

這篇就是我在這段過程中的技術筆記:
我從一個簡單的更新開始,一路拆解到「企業資料庫完整性」的全貌。


✉️ 1. 一次 Email 更新,帶出真正的盲點

原本以為:

UPDATE KGEIP.ORG_EMPLOYEE
SET EMAIL = REPLACE(EMAIL, '@old.com.tw', '@new.com.tw')
WHERE EMAIL LIKE '%@old.com.tw';

就能解決全部問題。

但更新之前我想到一件事:

如果資料表有 Trigger,而我沒有給完整欄位值,會不會讓 Trigger 報錯?

在企業級資料表中,MFDATMFMAN 等 audit
欄位非常常見,而這些欄位在不同系統裡可能被 Trigger 規範得很嚴。

我開始檢查 Trigger,發現該表沒有。但這也讓我回頭重新審視:
Trigger 到底應該扮演什麼角色?


🔥 2. Trigger 的真正用途(不只是審計)

Trigger 幾乎每個工程師都碰過,但它的「真實定位」常被誤解成只是審計使用。

其實 Trigger 在企業系統裡主要負責三件事:

① 自動補值(Auto-fill)✨

例如自動生成修改時間:

:NEW.MFDAT := SYSDATE;

② 保持資料一致性(Integrity)🛡️

例如不同表間名稱同步。

③ 事件級別的紀錄(History/Audit)📜

例如 INSERT/UPDATE/DELETE 時紀錄變動。

而這些 Trigger 的行為會在所有 DML 之後「無條件執行」,也就是:

程式怎麼寫不重要,最後都會由 Trigger 兜底。

這種設計強大,但也有另一面:

  • 隱藏邏輯(debug 困難)
  • 多個 trigger 可能衝突
  • Trigger 順序 Oracle 不保證
  • 大量寫入會拖垮效能

Trigger 用得好很強,用不好就變「企業級黑箱」。


🏗️ 3. Trigger vs Stored Procedure vs Constraint:三者的定位差異

這次更新讓我徹底釐清三者的本質。

以下是我整理的比較表:

項目 Trigger Stored Procedure Constraint
角色定位 自動反應的邏輯 可控的業務流程 基本格式與關聯
執行時機 被動、DML 時觸發 主動呼叫 任何 DML 自動驗證
可處理複雜度 中等
維護成本
典型用途 Audit、補值、跨表同步 批次、計算、流程控制 Unique、FK、Check

一句話總結:

  • Constraint:保證格式正確
  • Trigger:保證資料一致
  • Stored Procedure:保證流程正確

三者不是替代關係,而是三層不同防線。


🧾 4. 若希望「所有資料表變動都寫入 log」怎麼設計?

最常見的架構:

  • 一張 Log Header(誰改、什麼時候改)
  • 一張 Log Detail(欄位從多少 → 多少)
  • 一個共用的 audit package
  • 每張業務表掛一顆 Trigger,只負責呼叫 package

好處:

  • Trigger 樣板化
  • Audit 集中管理
  • 新增表只需新 trigger

但也會遇到:

  • 高頻變動表不能開太細的 log
  • Log 容量暴增
  • 暫存表不該 audit

Audit 應該被系統化,而不是硬寫 Trigger。


⏳ 5. Flashback 的盲點:它不是 Audit 的替代品

Flashback 解的是:

我想知道 5 分鐘前資料長怎樣?

但不是:

誰改了什麼欄位?

Flashback 適用:

  • 誤 DELETE
  • 查詢過去版本

不能取代:

  • 欄位差異紀錄
  • 修改人紀錄
  • 合規 audit
  • 多系統 log 整合
  • 高寫入表
  • 頻繁 DDL 的表

Flashback 是時光機,不是記錄器。


💥 6. DELETE、TRUNCATE、DROP:到底救不救得回來?

DELETE(未 commit)

ROLLBACK。

DELETE(已 commit)

Flashback Query → insert 回現表。

TRUNCATE

DDL → 隱含 commit → 幾乎不能救
只能依賴:

  • Flashback Table(有開的話)
  • RMAN 備份還原

DROP TABLE

若有 recycle bin → FLASHBACK TABLE
否則只能備份還原。

真正的搶救流程:

  1. 停止操作\
  2. 找 DBA\
  3. 記錄時間\
  4. 判斷能否 Flashback\
  5. 否則進行備份還原

關鍵反省:

如果開發者能 TRUNCATE 正式機,那是權限問題,不是技術問題。


🧠 7. 這次事件讓我真正學到的事

  • DML 背後都有隱藏風險\
  • Trigger 是補人性的安全網\
  • Flashback = 時間快照,不是 audit\
  • Audit 必須架構化\
  • 資料恢復能力是一家公司成熟度\
  • 權限控管比補救更重要

📝 GPT Prompt(未來問資料庫問題用)

我正在處理 Oracle/企業資料庫需求,請你從系統架構角度給我:
1. 支持性分析:確認我目前做法哪裡合理
2. 對立性視角:指出我沒看到的技術風險與盲點
3. 如果可能,提供安全的 SQL、Trigger/Audit 設計建議、恢復策略

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言