Oracle 10g 的虛擬私有資料庫(VPD)與傳統關聯視圖皆可實現列層級資料遮罩。本文透過薪資欄位遮罩案例,深度比較兩者在靈活性、維護性、共享池效能與應用透明度上的差異,助您選擇最適架構。
需求:當 DEPARTMENT_ID = 60 時,遮罩 SALARY 與 COMMISSION_PCT 欄位(顯示 NULL)。
CREATE OR REPLACE VIEW MASKED_SALARY_VIEW AS
SELECT FIRST_NAME, LAST_NAME,
CASE DEPARTMENT_ID WHEN 60 THEN NULL ELSE SALARY END AS SALARY,
CASE DEPARTMENT_ID WHEN 60 THEN NULL ELSE COMMISSION_PCT END AS COMMISSION_PCT,
DEPARTMENT_ID
FROM EMPLOYEES;
授權使用者僅存取視圖,不直接存取基底表。
若需求改為「使用者僅能看見自己部門的薪資」,視圖方案面臨:
CREATE OR REPLACE FUNCTION RLS_DEPT (OBJ_OWNER IN VARCHAR2, OBJ_NAME IN VARCHAR2)
RETURN VARCHAR2 AS
DEPTNO NUMBER;
PREDICATE VARCHAR2(200);
BEGIN
DEPTNO := SYS_CONTEXT('HR_CONTEXT', 'DEPT');
IF DEPTNO IS NULL THEN
PREDICATE := '1=2'; -- 全部遮罩
ELSE
PREDICATE := 'DEPARTMENT_ID = ' || DEPTNO;
END IF;
RETURN PREDICATE;
END;
/
BEGIN
DBMS_RLS.ADD_POLICY(
OBJECT_SCHEMA => 'HR',
OBJECT_NAME => 'EMPLOYEES',
POLICY_NAME => 'DEPT_SALARY_POLICY',
FUNCTION_SCHEMA => 'SECURITY_ADMIN',
POLICY_FUNCTION => 'RLS_DEPT',
SEC_RELEVANT_COLS => 'SALARY,COMMISSION_PCT',
SEC_RELEVANT_COLS_OPT => DBMS_RLS.ALL_ROWS
);
END;
/
| 維度 | 關聯視圖 | VPD |
|---|---|---|
| 策略集中管理 | 分散在多個視圖 | 單一策略函數 |
| 共享池效能 | 多 SQL 副本 | 單一 SQL 配合繫結變數 |
| 應用透明度 | 需修改查詢物件名 | 零修改,自動攔截所有存取 |
| 跨應用一致性 | 難以保證 | 資料庫層級強制生效 |
| 動態條件 | 靜態、難以參數化 | 支援 SYS_CONTEXT、SESSION 狀態 |
VPD 將安全邏輯下沉至資料庫核心,實現「資料自我保護」,是企業級資料治理的優選方案。