Share via


使用數據列篩選和數據行遮罩來篩選敏感數據

重要

這項功能處於公開預覽狀態

本文提供使用數據列篩選、數據行遮罩和對應數據表來篩選數據表中敏感數據的指引和範例。

什麼是數據列篩選?

數據列篩選可讓您將篩選套用至數據表,讓後續查詢只會傳回篩選述詞評估為 true 的數據列。 數據列篩選會實作為 SQL 使用者定義函數 (UDF)。

若要建立數據列篩選,請先撰寫 SQL UDF 來定義篩選原則,然後使用 語句將它套用至數據表 ALTER TABLE 。 或者,您可以在初始 CREATE TABLE 語句中指定資料表的數據列篩選。 每個數據表只能有一個數據列篩選。 數據列篩選會接受零個或多個輸入參數,其中每個輸入參數都會系結至對應數據表的一個數據行。

這些篩選和動態檢視之間的差異為何?

動態檢視是一或多個源數據表的抽象只讀檢視。 用戶可以存取動態檢視,而不需要直接存取源數據表。 建立動態檢視會定義新的數據表名稱,該名稱不得符合存在於相同架構中的任何源數據表或其他數據表和檢視表的名稱。

另一方面,將數據列篩選或數據行遮罩關聯至目標數據表,會將對應的邏輯直接套用至數據表本身,而不會引入任何新的數據表名稱。 後續查詢可能會繼續使用其原始名稱直接參考目標數據表。

動態檢視和數據列篩選和數據行遮罩都可讓您將複雜的邏輯套用至數據表,並在查詢運行時間處理其篩選決策。

如果您需要將篩選和遮罩等轉換邏輯套用至唯讀數據表,而且使用者可以使用不同的名稱參考動態檢視,請使用動態檢視。 如果您想要篩選或計算特定數據上的表達式,但仍提供使用者使用其原始名稱來存取數據表,請使用數據列篩選和數據行遮罩。

數據列篩選語法

若要建立數據列篩選,並將其新增至現有的數據表,請使用下列語法:

建立資料列篩選:

CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {filter clause whose output must be a boolean};

將資料列篩選套用至資料表:

ALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<column_name>, ...);

從資料表中移除資料列篩選:

ALTER TABLE <table_name> DROP ROW FILTER;

變更資料列篩選:

Run a DROP FUNCTION statement to drop the existing function, or use CREATE OR REPLACE FUNCTION to replace it.

刪除資料列篩選:

ALTER TABLE <table_name> DROP ROW FILTER;
DROP FUNCTION <function_name>;

注意

您必須先執行 ALTER TABLE ... DROP ROW FILTER 命令,才能卸除函式或數據表處於無法存取的狀態。

如果數據表以這種方式變得無法存取,請使用 來改變數據表並卸除孤立的數據列篩選參考 ALTER TABLE <table_name> DROP ROW FILTER;

數據列篩選範例

建立套用至區域中US群組admin成員的 SQL 使用者定義函式。

使用此函式,群組的成員 admin 可以存取數據表中的所有記錄。 如果非系統管理員呼叫函式,條件 RETURN_IF 會失敗並評估表達式,並 region='US' 篩選數據表,只顯示區域中的 US 記錄。

CREATE FUNCTION us_filter(region STRING)
RETURN IF(IS_ACCOUNT_GROUP_MEMBER('admin'), true, region='US');

將函式套用至數據表做為數據列篩選。 然後,數據表的 sales 後續查詢會傳回數據列的子集。

CREATE TABLE sales (region STRING, id INT);
ALTER TABLE sales SET ROW FILTER us_filter ON (region);

停用數據列篩選。 未來的使用者查詢會從 sales 數據表傳回數據表中的所有數據列。

ALTER TABLE sales DROP ROW FILTER;

使用套用做為 CREATE TABLE 語句一部分的數據列篩選來建立數據表。 數據表的未來查詢 sales 會傳回數據列的子集。

CREATE TABLE sales (region STRING, id INT)
WITH ROW FILTER us_filter ON (region);

什麼是數據行遮罩?

數據行遮罩可讓您將遮罩函式套用至數據表數據行。 遮罩函式會在查詢運行時間進行評估,並以遮罩函式的結果取代目標數據行的每個參考。 針對大部分的使用案例,數據行遮罩會決定是否要傳回原始數據行值,或根據叫用使用者的身分識別加以修訂。 數據行遮罩是寫入為 SQL UDF 的表達式。

每個數據表數據行都可以選擇性地套用一個遮罩函式。 遮罩函式會接受數據行的未遮罩值做為輸入,並傳回遮罩值作為結果。 遮罩函式的傳回值應該與遮罩的數據行相同。 遮罩函式也可以採用其他數據行作為輸入參數,並在遮罩邏輯中使用它們。

若要套用數據行遮罩,請建立函式,並使用語句將它套用 ALTER TABLE 至數據表數據行。 或者,您可以在建立數據表時套用遮罩函式。

數據行遮罩語法

在 子句中 MASK ,您可以使用任何 Azure Databricks 內建運行時間函式,或呼叫其他使用者定義函式。 常見的使用案例包括檢查叫用 current_user( ) 函式的使用者身分識別,或是使用 is_account_group_member( )所屬群組。

建立資料行遮罩:

CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {expression with the same type as the first parameter};

將資料列遮罩套用至現有資料表中的資料列:

ALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> [USING COLUMNS <additional_columns>];

從資料表中的資料列移除資料列遮罩:

ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;

修改資料列遮罩:

DROP現有函式或使用 CREATE OR REPLACE TABLE

刪除資料列遮罩:

ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
DROP FUNCTION <function_name>;

注意

您必須先執行 ALTER TABLE 命令,才能卸除函式或數據表處於無法存取的狀態。

如果數據表以這種方式無法存取,請使用 來改變數據表並卸除孤立的遮罩參考參考 ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;

數據行遮罩範例

在此範例中,您會建立使用者 ssn 定義函式來遮罩數據行,讓只有屬於群組成員的使用者 HumanResourceDept 才能檢視該數據行中的值。

CREATE FUNCTION ssn_mask(ssn STRING)
  RETURN CASE WHEN is_member('HumanResourceDept') THEN ssn ELSE '***-**-****' END;

將新的函式套用至數據表作為數據行遮罩。 您可以在建立資料表或之後新增數據行遮罩。

--Create the `users` table and apply the column mask in a single step:

CREATE TABLE users (
  name STRING,
  ssn STRING MASK ssn_mask);
--Create the `users` table and apply the column mask after:

CREATE TABLE users
  (name STRING, ssn STRING);

ALTER TABLE users ALTER COLUMN ssn SET MASK ssn_mask;

當查詢使用者不是群組的成員時,該數據表上的查詢現在會傳回遮罩 ssn 的數據 HumanResourceDept 行值:

SELECT * FROM users;
  James  ***-**-****

若要停用數據行遮罩,讓查詢傳回數據行中的 ssn 原始值:

ALTER TABLE users ALTER COLUMN ssn DROP MASK;

使用對應數據表來建立訪問控制清單

若要達到數據列層級安全性,請考慮定義對應數據表(或訪問控制清單)。 每個對應數據表都是一個完整的對應數據表,可編碼某些使用者或群組可存取原始數據表中的數據列。 對應數據表很有用,因為它們透過直接聯結提供與事實數據表的簡單整合。

此方法可證明有助於解決許多具有自定義需求的使用案例。 範例包含:

  • 根據登入的使用者施加限制,同時容納特定使用者群組的不同規則。
  • 建立複雜的階層,例如組織結構,需要各種規則集。
  • 從外部來源系統復寫複雜的安全性模型。

透過這種方式採用對應數據表,您可以有效地處理這些具挑戰性的案例,並確保健全的數據列層級和數據行層級安全性實作。

對應數據表範例

使用對應資料表來檢查目前使用者是否在清單中:

USE CATALOG main;

建立新的對應資料表:

DROP TABLE IF EXISTS valid_users;

CREATE TABLE valid_users(username string);
INSERT INTO valid_users
VALUES
  ('fred@databricks.com'),
  ('barney@databricks.com');

建立新的篩選:

注意

除了檢查使用者內容 (例如 CURRENT_USER , 和 IS_MEMBER 函式) 以叫用者身分執行的函式之外,所有篩選條件都會以定義器的許可權執行。

在此範例中,函式會檢查目前使用者是否在數據表中 valid_users 。 如果找到使用者,函式會傳回 true。

DROP FUNCTION IF EXISTS row_filter;

CREATE FUNCTION row_filter()
  RETURN EXISTS(
    SELECT 1 FROM valid_users v
    WHERE v.username = CURRENT_USER()
);

下列範例會在數據表建立期間套用數據列篩選。 您也可以稍後使用 ALTER TABLE 語句來新增篩選。 套用至整個數據表時, ON () 請使用 語法。 針對特定資料列,請使用 ON (row);

DROP TABLE IF EXISTS data_table;

CREATE TABLE data_table
  (x INT, y INT, z INT)
  WITH ROW FILTER row_filter ON ();

INSERT INTO data_table VALUES
  (1, 2, 3),
  (4, 5, 6),
  (7, 8, 9);

從數據表中選取數據。 只有當用戶位於數據表中 valid_users 時,才應該傳回數據。

SELECT * FROM data_table;

建立對應數據表,其中包含一律可以檢視數據表中所有數據列的帳戶,而不論數據行值為何:

CREATE TABLE valid_accounts(account string);
INSERT INTO valid_accounts
VALUES
  ('admin'),
  ('cstaff');

現在建立 SQL UDF,如果資料列中所有資料行的值小於五,或叫用使用者是上述對應數據表的成員,則會傳回 true

CREATE FUNCTION row_filter_small_values (x INT, y INT, z INT)
  RETURN (x < 5 AND y < 5 AND z < 5)
  OR EXISTS(
    SELECT 1 FROM valid_accounts v
    WHERE IS_ACCOUNT_GROUP_MEMBER(v.account));

最後,將 SQL UDF 套用至資料表作為數據列篩選:

ALTER TABLE data_table SET ROW FILTER row_filter_small_values ON (x, y, z);

支援能力

  • 支援適用於 SQL 工作負載的 Databricks SQL 和 Databricks 筆記本。
  • 支援具有MODIFY許可權的使用者 DML 命令。 篩選和遮罩會套用至 UPDATEEs 和 DELETE 讀取的數據,而且不會套用至寫入的數據(包括 INSERTed 數據)。
  • 支援的格式:Delta 和 Parquet。 僅受管理或外部數據表支援 Parquet。
  • 支援具有數據行遮罩或數據列篩選的數據表檢視。
  • 只要架構與可能套用至目標數據表的數據列篩選和數據行遮罩相容,就支援 Delta Lake 變更數據摘要。
  • 支援外部數據表。

限制

  • 低於 12.2 LTS 的 Databricks 執行時間版本不支援資料列篩選或數據行遮罩。 這些運行時間會安全地失敗,這表示如果您嘗試從這些運行時間不支援的版本存取數據表,則不會傳回任何數據。
  • 差異實時數據表具體化檢視和串流數據表不支援數據列篩選或數據行遮罩。
  • Python 和 Scala UDF 不支援直接作為數據列篩選或數據行遮罩函式。 不過,只要這些定義永久儲存在目錄中,就可以在 SQL UDF 中參考這些定義(換句話說,而不是暫時儲存在會話中)。
  • 差異共用不適用於數據列層級安全性或數據行遮罩。
  • 時間移動不適用於數據列層級安全性或數據行遮罩。
  • 數據表取樣不適用於數據列層級安全性或數據行遮罩。
  • 目前不支援使用原則之數據表中檔案的路徑型存取。
  • 不支援具有迴圈相依性的數據列篩選或數據行遮罩原則回到原始原則。
  • MERGE 不支援淺層複製。

單一使用者叢集限制

請勿將數據列篩選或數據行遮罩新增至您要從單一使用者叢集存取的任何數據表。 這通常是在 Azure Databricks 作業的內容中完成。 在公開預覽期間,一旦套用篩選或遮罩,您將無法從單一使用者叢集存取數據表。