虛擬私有資料庫(Virtual Private Database, VPD)是 Oracle 8i 起引入的細粒度存取控制技術,10g 大幅增強策略類型,提供更靈活的效能調優選項。本文解析 VPD 運作原理、五大策略類型差異,並給出選型建議。
VPD 透過安全策略函數動態產生謂詞,透明改寫使用者查詢。例如:
-- 原始查詢
SELECT * FROM accounts;
-- VPD 自動改寫(假設策略函數回傳 'am_name = ''SCOTT''')
SELECT * FROM accounts WHERE am_name = 'SCOTT';
策略函數回傳的 WHERE 子句字串會被附加到所有存取該表/視圖的查詢中,實現資料列級安全。
| 策略類型 | 重新評估頻率 | 適用場景 | 效能特徵 |
|---|---|---|---|
| DYNAMIC(預設) | 每次查詢、每列 | 謂詞高度動態(依使用者、時間、語境變化) | CPU 開銷最大,但最彈性 |
| STATIC | 物件載入時一次 | 謂詞完全固定(如固定部門代碼) | 零執行期開銷,但無法適應變化 |
| CONTEXT_SENSITIVE | 應用語境變更時 | 謂詞前綴固定,後綴依語境(如 SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER')) | 大幅減少函數呼叫,平衡彈性與效能 |
| SHARED_CONTEXT_SENSITIVE | 共享語境變更時 | 多用戶共享相同語境值(如多租戶共用應用代碼) | 進一步降低評估次數 |
| SHARED_STATIC | 啟動時一次 | 跨會話共享的靜態謂詞 | 最低開銷,極少見 |
以 WHERE am_name = 'SCOTT' 為例:
am_name = 為靜態前綴(欄位、運算子固定)'SCOTT' 為動態後綴(依使用者身份變化)使用 CONTEXT_SENSITIVE 策略時,Oracle 只在應用語境(DBMS_SESSION.SET_CONTEXT)變更時重新評估函數,而非每列每查詢都評估,大幅降低 CPU 消耗。
BEGIN
DBMS_RLS.ADD_POLICY(
object_schema => 'SCOTT',
object_name => 'ACCOUNTS',
policy_name => 'ACCOUNT_VPD_POL',
function_schema => 'SEC_ADMIN',
policy_function => 'GEN_ACCOUNT_PREDICATE',
policy_type => DBMS_RLS.CONTEXT_SENSITIVE, -- 關鍵:指定策略類型
sec_relevant_cols => 'AM_NAME'
);
END;
/
STATICCONTEXT_SENSITIVE(首選)SHARED_CONTEXT_SENSITIVEDYNAMIC(預設,向後相容)SYS_CONTEXT 傳遞應用語境,而非直接讀取表,確保效能。SELECT FOR UPDATE、MERGE、FLASHBACK QUERY 等部分語法,測試時需驗證。善用 10g 引入的策略類型,能在不犧牲安全性的前提下,將 VPD 的執行期開銷降至最低,是大型企業級應用實現多租戶、資料隔離的關鍵技術。