首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 細粒度存取控制(VPD)核心機制與策略類型深度解析

     編輯:Oracle 資料庫基礎

什麼是 VPD?

Virtual Private Database(VPD,虛擬私有資料庫)是 Oracle 8i 引入的行級安全功能。它透過動態修改用戶查詢、在 WHERE 子句自動附加謂詞,實現「同一張表、不同用戶看到不同資料」的效果,且對應用程式完全透明。

核心運作流程

  1. DBA 在目標表建立安全策略,關聯一個 Policy Function(策略函數)。
  2. 用戶執行查詢(如 SELECT * FROM accounts)。
  3. Oracle 在執行前呼叫策略函數,取回謂詞字串(如 am_name = 'SCOTT')。
  4. 查詢被重寫為 SELECT * FROM accounts WHERE am_name = 'SCOTT' 並執行。

策略函數的動態本質與效能代價

謂詞通常包含 靜態部分(欄位名、運算子)與 動態部分(用戶身分、權限、應用上下文變數)。在 Oracle 9i 及之前,預設為 Dynamic Policy:每次查詢、每行資料都重新執行策略函數,對高併發系統造成巨大 CPU 開銷。

Oracle 10g 引入的四種進階策略類型

針對謂詞「靜態程度」不同,提供效能優化選項:

1. Context-Sensitive Policy(上下文敏感策略)

適用場景:謂詞結構固定,僅應用上下文變數(如 SYS_CONTEXT('vpdctx', 'maxbal'))隨會話改變。

機制:若會話期間上下文屬性未變,Oracle **跳過策略函數重新執行**,直接復用上次謂詞。

DBMS_RLS.ADD_POLICY(..., policy_type => DBMS_RLS.CONTEXT_SENSITIVE);

2. Static Policy(靜態策略)

適用場景:謂詞完全由資料庫用戶決定,會話間不變(如多租戶共用 APPUSER,登入觸發器設定 CUST_NAME)。

機制:謂詞在 SGA 快取,**策略函數僅執行一次**(首次解析時),後續查詢直接復用,速度最快。

DBMS_RLS.ADD_POLICY(..., policy_type => DBMS_RLS.STATIC);

⚠️ 風險:若會話中上下文實際被修改,靜態策略**不會重新評估**,導致資料洩露或錯誤。除非 100% 確定上下文不變,否則寧選 Context-Sensitive。

3. Shared Context-Sensitive / Shared Static(共享策略)

適用場景:多張表(如 SAVINGS、CHECKING)共用同一策略函數,且上下文相同。

機制:跨物件共用謂詞快取,避免切換表時重複執行函數。

policy_type => DBMS_RLS.SHARED_CONTEXT_SENSITIVE
policy_type => DBMS_RLS.SHARED_STATIC

策略選擇決策樹

  1. 謂詞每次查詢都完全不同(含隨機因子)→ Dynamic(預設)
  2. 謂詞結構固定,僅上下文變數改變 → Context-Sensitive
  3. 謂詞完全由 DB User 決定,會話不變 → Static(謹慎用)
  4. 多表共用函數 + 上述條件 → 對應 Shared_* 版本

最佳實踐建議

  • 優先使用 Context-Sensitive:平衡效能與安全,適用 90% 以上場景。
  • 策略函數內**避免複雜查詢**,僅組裝謂詞字串;必要時將邏輯下推至應用層設定上下文。
  • 善用 DBMS_RLS.ADD_POLICY 的 SEC_RELEVANT_COLS 與 SEC_RELEVANT_COLS_OPT 實現「列級掩碼」而非行級過濾。
  • 定期查詢 DBA_POLICIES、V$VPD_POLICY 監控策略命中率與執行耗時。

結語

VPD 是 Oracle 資料庫層面實現行級安全的利器,關鍵在於**根據謂詞動態程度選對策略類型**。「動態」最安全但最慢,「靜態」最快但風險最高,「上下文敏感」是黃金平衡點。架構師應在設計階段即規劃上下文命名空間與策略分類,而非事後補丁。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved