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

Oracle 10g VPD 細粒度存取控制:五種策略類型深度解析與效能優化

     編輯:Oracle 資料庫基礎

前言

虛擬私有資料庫 (VPD, Virtual Private Database) 是 Oracle 8i 推出的行級安全功能,透過動態修飾查詢謂詞實現資料隔離。Oracle 10g 引入四種新策略類型,針對謂詞動態性質提供精細的快取與重新評估控制,大幅提升高併發環境下的效能。本文深度解析 Dynamic、Context-Sensitive、Shared Context-Sensitive、Shared Static、Static 五種策略類型的運作機制、適用場景與效能特徵。

一、VPD 核心運作原理

  • 安全策略定義於表/視圖/同義詞上
  • 策略函數回傳 WHERE 條件謂詞字串 (如 dept_id = 10)
  • 查詢重寫:SELECT * FROM emp → SELECT * FROM emp WHERE dept_id = 10
  • 透明於應用,無需修改 SQL

二、謂詞結構分析:靜態部份 vs 動態部份

以 WHERE am_name = 'SCOTT' 為例:

  • 靜態部份:am_name = (欄位名、運算子)
  • 動態部份:'SCOTT' (依用戶身分、權限、上下文變化)

關鍵洞見:靜態部份不變時,動態部份若可從穩定上下文取得,即可避免重複執行策略函數。

三、五種策略類型詳細比較

策略類型DBMS_RLS 常數重新評估條件快取層級適用場景
Dynamic (動態)DBMS_RLS.DYNAMIC (預設)每次查詢、每行、每用戶無謂詞高度動態、依賴即時計算、向後相容
Context-Sensitive (上下文敏感)DBMS_RLS.CONTEXT_SENSITIVE應用上下文 (SYS_CONTEXT) 變化時會話級 (SGA)謂詞依賴應用上下文、上下文會話期間相對穩定
Shared Context-Sensitive (共享上下文敏感)DBMS_RLS.SHARED_CONTEXT_SENSITIVE上下文變化 或 物件不同但函數相同時跨物件共享 (SGA)多表共用同一策略函數、上下文相同
Static (靜態)DBMS_RLS.STATIC僅首次執行,之後永不重新評估SGA 永久快取謂詞完全由登入用戶決定、會話期間不變 (如多租戶 SaaS)
Shared Static (共享靜態)DBMS_RLS.SHARED_STATIC僅首次執行,跨物件共享跨物件 SGA 永久快取多表共用靜態策略函數

四、各類型實作範例

1. Dynamic (預設,向後相容)

BEGIN
  DBMS_RLS.ADD_POLICY(
    object_schema   => 'HR',
    object_name     => 'EMPLOYEES',
    policy_name     => 'EMP_DYNAMIC_POL',
    function_schema => 'SECURITY',
    policy_function => 'GET_EMP_PREDICATE',
    policy_type     => DBMS_RLS.DYNAMIC
  );
END;

2. Context-Sensitive:依賴應用上下文

-- 策略函數
CREATE OR REPLACE FUNCTION get_balance_predicate(
  p_schema IN VARCHAR2, p_table IN VARCHAR2
) RETURN VARCHAR2 IS
BEGIN
  RETURN 'balance < SYS_CONTEXT(''VPD_CTX'', ''MAX_BAL'')';
END;

-- 註冊策略
BEGIN
  DBMS_RLS.ADD_POLICY(
    policy_type => DBMS_RLS.CONTEXT_SENSITIVE,
    -- 其他參數同上
  );
END;

-- 應用登入後設定上下文
BEGIN
  DBMS_SESSION.SET_CONTEXT('VPD_CTX', 'MAX_BAL', 100000);
END;

效能機制:會話期間 MAX_BAL 不變 → 策略函數不重新執行 → 謂詞從 SGA 快取取得。

3. Static:完全靜態謂詞

CREATE OR REPLACE FUNCTION get_cust_predicate(
  p_schema IN VARCHAR2, p_table IN VARCHAR2
) RETURN VARCHAR2 IS
BEGIN
  RETURN 'cust_name = SYS_CONTEXT(''VPD_CTX'', ''CUST_NAME'')';
END;

BEGIN
  DBMS_RLS.ADD_POLICY(
    policy_type => DBMS_RLS.STATIC,
    -- 其他參數
  );
END;

風險警示:若會話中 CUST_NAME 上下文被修改,策略函數不會重跑 → 回傳錯誤資料!
鐵律:只有 100% 確定會話期間上下文不變時才用 STATIC,否則改用 CONTEXT_SENSITIVE。

4. Shared Context-Sensitive:跨表共享

-- SAVINGS 與 CHECKING 表共用同一策略函數
BEGIN
  DBMS_RLS.ADD_POLICY(object_name => 'SAVINGS',   policy_type => DBMS_RLS.SHARED_CONTEXT_SENSITIVE, ...);
  DBMS_RLS.ADD_POLICY(object_name => 'CHECKING', policy_type => DBMS_RLS.SHARED_CONTEXT_SENSITIVE, ...);
END;

效能增益:同會話查詢 SAVINGS 再查 CHECKING,上下文未變 → 策略函數不重跑,直接複用謂詞快取。

五、策略選擇決策樹

謂詞是否每次查詢都不同?
  ├─ 是 → DYNAMIC (無快取)
  └─ 否 → 謂詞是否依賴應用上下文?
        ├─ 否 → 謂詞是否僅依賴登入用戶 (會話不變)?
        │       ├─ 是 → STATIC (最快,但風險最高)
        │       └─ 否 → CONTEXT_SENSITIVE (平衡)
        └─ 是 → 是否多表共用同一函數?
                ├─ 是 → SHARED_CONTEXT_SENSITIVE
                └─ 否 → CONTEXT_SENSITIVE

六、效能量化對比 (典型 OLTP 負載)

策略類型策略函數執行次數/秒CPU 開銷延遲影響
Dynamic高 (每查詢每行)高明顯
Context-Sensitive低 (上下文變化時)低微乎其微
Shared Context-Sensitive極低 (跨表複用)極低無
Static1 (首次)最低無

七、最佳實務建議

  1. 預設用 Context-Sensitive:安全性與效能最佳平衡點
  2. Static 僅用於多租戶 SaaS 登入觸發器設定上下文場景,並加註解警示
  3. 共享策略:識別共用安全邏輯的表群,統一註冊 SHARED_* 類型
  4. 上下文命名規範:VPD_<業務域>_<屬性>,避免衝突
  5. 審計與監控:啟用 DBMS_RLS.ADD_POLICY 的 sec_relevant_cols、sec_relevant_cols_opt 進行欄位級保護
  6. 測試驗證:自動化測試覆蓋上下文變更、多表查詢、併發會話場景

結語

Oracle 10g VPD 策略類型演進,本質上是謂詞快取粒度與失效條件的精細控制。從 Dynamic 的零快取到 Static 的永久快取,中間的 Context-Sensitive 與 Shared 系列提供了豐富的效能調優槓桿。核心原則:謂詞靜態部份越多、動態部份來源越穩定 (應用上下文 vs 即時計算)、共用範圍越廣 (跨表/跨會話),效能增益越大。實務中建議以 Context-Sensitive 為基準,經效能測試驗證後,再針對熱點表升級為 Shared Context-Sensitive 或謹慎降級為 Static,構建安全且高效的行級存取控制體系。

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