使用資料列篩選和資料行遮罩來篩選敏感資料表資料
本文提供使用資料列篩選、資料行遮罩和對應資料表來篩選資料表中敏感資料的指引和範例。 這些功能需要 Unity Catalog。
什麼是資料列篩選?
資料列篩選可讓您將篩選套用至資料表,讓查詢只傳回符合篩選準則的資料列。 您會將資料列篩選實作為 SQL 使用者定義的函式 (UDF)。 Python 和 Scala UDF 也受到支援,但前提是它們裝合在 SQL UDF 中。
什麼是資料行遮罩?
資料行遮罩可讓您將遮罩函式套用至資料表資料行。 遮罩函式會在查詢執行階段進行評估,並以遮罩函式的結果取代目標資料行的每個參考。 針對大部分使用案例,資料行遮罩會決定是否要傳回原始資料行值,或根據叫用使用者的身分加以修訂。 資料行遮罩是寫入為 SQL UDF 或 Python 或 Scala UDF 的運算式,這些運算式裝合在 SQL UDF 中。
每個資料表資料行只能套用一個遮罩函式。 遮罩函式會接受資料行的未遮罩值做為輸入,並傳回遮罩值作為結果。 遮罩函式的傳回值應該與要遮罩的資料行的類型相同。 遮罩函式也可以採用其他資料行作為輸入參數,並在遮罩邏輯中使用它們。
這些篩選和動態檢視之間的差異為何?
動態檢視、資料列篩選和資料行遮罩全都可讓您將複雜的邏輯套用至資料表,並在查詢執行階段處理其篩選決策。
動態檢視是一個或多個源資料表的抽象唯讀檢視。 使用者可以存取動態檢視,而不需要直接存取來源資料表。 建立動態檢視會定義新的資料表名稱,該名稱不得與相同結構描述中的任何來源資料表或其他資料表和檢視表的名稱相同。
另一方面,將資料列篩選或資料行遮罩關聯至目標資料表,會將對應的邏輯直接套用至資料表本身,而不需要引入新的資料表名稱。 後續查詢可以使用其原始名稱,繼續直接參考目標資料表。
如果需要將篩選和遮罩等轉換邏輯套用至唯讀資料表,而且使用者可以使用不同的名稱參考動態檢視,請使用動態檢視。 如果想要使用 Delta Sharing 來篩選資料,則必須使用動態檢視。 如果想要篩選或計算特定資料上的運算式,但仍允許使用者使用其原始名稱來存取資料表,請使用資料列篩選和資料行遮罩。
開始之前
若要將資料列篩選和資料行遮罩新增至資料表,您必須具有:
- 已為 Unity Catalog 啟用的工作區。
- 在 Unity Catalog 中註冊的函式。 這可以是 SQL UDF,或在 Unity Catalog 中註冊並包裝在 SQL UDF 中的 Python 或 Scala UDF。 如需詳細資訊,請參閱什麼是使用者定義的函式 (UDF)?、資料行遮罩子句和 ROW FILTER 子句。
也必須滿足下列需求:
- 若要指派將資料列篩選或資料行遮罩加入資料表的函式,您必須擁有函式的
EXECUTE
權限、結構描述的USE SCHEMA
權限和父目錄的USE CATALOG
權限。 - 如果要在建立新資料表時新增篩選或遮罩,則必須擁有結構描述的
CREATE TABLE
權限。 - 如果要將篩選或遮罩新增至現有資料表,您必須是資料表擁有者,或同時擁有資料表的
MODIFY
和SELECT
權限。
若要存取具有資料列篩選或資料行遮罩的資料表,您的計算資源必須符合下列其中一項需求:
SQL 倉儲。
Databricks Runtime 12.2 LTS 或更高版本中的共用存取模式。
Databricks Runtime 15.4 LTS 或更新版本上的單一使用者存取模式。
您無法在 Databricks Runtime 15.3 或以下使用單一使用者計算來讀取數據列篩選或數據行遮罩。
若要利用 Databricks Runtime 15.4 LTS 及更高版本提供的資料篩選功能,還必須確認您的工作區已啟用無伺服器運算,因為支援資料列篩選和資料行遮罩的資料篩選功能會在無伺服器運算上執行。 因此,當您使用單一使用者計算來讀取使用數據列篩選或數據行遮罩的數據表時,可能會向您收取無伺服器計算資源的費用。 請參閱 單一用戶計算的細微訪問控制。
套用資料列篩選
若要建立資料列篩選,可以撰寫函式 (UDF) 來定義篩選原則,然後將它套用至資料表。 每個資料表只有一個資料列欄位。 資料列篩選會接受零個或多個輸入參數,其中每個輸入參數都會繫結至對應資料表的一個資料行。
您可以使用目錄總管或 SQL 命令來套用資料列篩選。 目錄總管指令假設您已建立函式,且已在 Unity Catalog 中註冊。 SQL 指令包含建立資料列篩選函式並將其套用至資料表的範例。
目錄總管
- 在 Azure Databricks 工作區中,按一下 [目錄]。
- 瀏覽或搜尋要篩選的資料表。
- 在 [概觀] 索引標籤上,按一下 [資料列篩選:新增篩選]。
- 在 [新增資料列篩選] 對話框中,選取包含篩選函式的目錄和結構描述,然後選取函式。
- 在展開的對話方塊中,檢視函式定義,然後選取符合函式陳述式中所含資料行的資料表資料行。
- 按一下新增。
若要從資料表中移除篩選,請按一下 [fx 資料列篩選],然後按一下 [移除]。
SQL
若要建立資料列篩選,然後將它新增至現有的資料表,請使用 CREATE FUNCTION
,並使用 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> SET ROW FILTER <function_name> ON (<constant_literal>, ...);
從資料表中移除資料列篩選:
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;
來改變資料表並卸除孤立的資料列篩選參考。
另請參閱 ROW FILTER 子句。
資料列篩選範例
此範例會建立 SQL 使用者定義的函式,它可套用至區域 US
中群組 admin
的成員。
當此範例函式套用至 sales
資料表時,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);
套用資料行遮罩
若要套用資料行遮罩,請建立函式 (UDF),然後將它套用至資料表資料行。
可以使用目錄總管或 SQL 命令來套用資料行遮罩。 目錄總管指令假設您已建立函式,且已在 Unity Catalog 中註冊。 SQL 指令包含建立資料行遮罩函式並將其套用至資料表資料行的範例。
目錄總管
- 在 Azure Databricks 工作區中,按一下 [目錄]。
- 瀏覽或搜尋資料表。
- 在 [概觀] 索引標籤上,尋找您要套用資料行遮罩的資料列,然後按一下 [遮罩] 編輯圖示。
- 在 [新增資料行遮罩] 對話框中,選取包含篩選函式的目錄和結構描述,然後選取函式。
- 在展開的對話方塊中,檢視函式定義。 如果除了要遮罩的資料行之外,函式還包含任何參數,請選取您要為其分配這些其他函式參數的資料表資料行。
- 按一下新增。
若要從資料表中移除資料行遮罩,請按一下資料表資料列中的 [fx 資料行遮罩],然後按一下 [移除]。
SQL
若要建立資料行遮罩,並將它新增至現有的資料表資料行,請使用 CREATE FUNCTION
,並使用 ALTER TABLE
來套用遮罩函式。 您也可以在使用 CREATE TABLE
建立資料表時套用函式。
使用 SET MASK
來套用遮罩函式。 在 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 <col_name> SET MASK <mask_func_name> USING COLUMNS (<constant_name>, ...);
從資料表的資料行中移除資料行遮罩:
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;
當查詢使用者不是 HumanResourceDept
群組的成員時,該資料表上的查詢現在會傳回已遮罩的 ssn
資料行值:
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);
支援和限制
所有 Azure Databricks 功能或所有計算資源都不支援資料列篩選和資料行遮罩。 本節列出支援的功能和限制。
支援的功能和格式
此支援的功能清單並不詳盡。 會列出某些項目,因為它們在公開預覽期間不受支援。
支援適用於 SQL 工作負載的 Databricks SQL 和 Databricks 筆記本。
支援具有
MODIFY
權限的使用者執行 DML 命令。 篩選和遮罩會套用至UPDATE
和DELETE
陳述式讀取的資料,而且不會套用至寫入的資料 (包括INSERT
)。支援的資料格式:
- 受控和外部資料表的 Delta 和 Parquet。
- 使用 Lakehouse Federation 在 Unity Catalog 中註冊之外部資料表的多個其他資料格式。
原則參數可包含常數運算式 (字串、數值、間隔、布林值、Null)。
只要在 Unity Catalog 中註冊 SQL、Python 和 Scala UDF,就支援它們作為資料列篩選或資料行遮罩函式。 Python 和 Scala UDF 必須裝合在 SQL UDF 中。
可以在參考資料行遮罩或資料列篩選的資料表上建立檢視,但無法將資料行遮罩或資料列篩選新增至檢視。
只要結構描述與套用至目標資料表的資料列篩選和資料行遮罩相容,就支援 Delta Lake 變更資料摘要。
支援外部資料表。
支援資料表取樣。
當來源資料表、目標資料表或兩者同時使用資料列篩選和資料行遮罩時,支援
MERGE
陳述式。 這包括包含簡單子查詢之資料列篩選函式的資料表,但也有一些限制,在後面一節會列出。Databricks SQL 具體化檢視和 Databricks SQL 串流資料表支援資料列篩選和資料行遮罩 (公開預覽):
- 您可以將資料列篩選和資料欄遮罩新增至 Databricks SQL 具體化檢視或串流資料表。 定義具體化檢視或串流數據表時,必須以宣告方式完成此作業。 請參閱 CREATE MATERIALIZED VIEW 或 CREATE STREAMING TABLE。
- 您可以在包含資料列篩選和資料欄遮罩的資料表上定義 Databricks SQL 具體化檢視或串流資料表。
在 Delta Live Tables 中宣告和發佈的具體化檢視和串流資料表支援資料列篩選或資料行遮罩 (公開預覽):
- 您可以將資料列篩選和資料欄遮罩新增至 Delta Live Tables 具體化檢視或串流資料表。
- 您可以在包含資料列篩選和資料欄遮罩的資料表上定義 Delta Live Tables 具體化檢視或串流資料表。
效能考慮
資料列篩選和資料行遮罩可保證資料的可見度,方法是確保使用者在篩選和遮罩操作之前無法檢視基底資料表值的內容。 它們被設計為在回應最常見使用案例的查詢時表現良好。 在較不頻繁的應用程式中,查詢引擎必須在優化查詢效能和防止洩漏已篩選/已遮罩值的資訊中做出選擇,它總是會以對查詢效能造成一些影響為代價做出安全決策。 若要將此效能影響降到最低,請套用下列準則:
- 使用簡單的原則函式:具有較少運算式的原則函式通常會比更複雜的運算式執行得更好。 請避免使用對應資料表和運算式子查詢,而使用簡單的 CASE 函式。
- 減少函式引數的數目:即使查詢中未使用這些資料行,Azure Databricks 也無法優化原則函式引數產生的對來源資料表的資料行參考。 使用具有較少引數的原則函式,因為這些資料表的查詢通常會執行得更好。
- 避免新增帶有太多 AND 連詞的資料列篩選條件:因為每個資料表最多只支援新增一個資料列篩選條件,常見的方法是將多個所需的原則函式與
AND
結合。 不過,對於每個聯接,聯接包含本資料表其他地方提到的會影響效能 (例如,使用對應資料表) 的元件的可能性會增加。 使用較少的連詞來改善效能。 - 使用無法在資料表原則和這些資料表的查詢中擲回錯誤的確定性運算式:如果提供的輸入無效,某些運算式可能會擲回錯誤,例如 ANSI 劃分。 在這種情況下,SQL 編譯器不得使用這些運算式 (例如篩選條件) 在查詢計劃中將操作下推太遠,以避免在篩選和/或遮罩操作之前出現「除以零」之類的錯誤,這些錯誤會顯示有關值的資訊。 使用具有確定性且永遠不會擲回錯誤的運算式,例如此範例中的
try_divide
。 - 在資料表上執行測試查詢以量測效能:建構實際查詢,它代表您預期具有資料列篩選和/或資料行遮罩的資料表的工作負載,並測量效能。 對原則函式進行小幅修改並觀察其效果,直到在篩選和遮罩邏輯的效能與表達性之間達到良好平衡為止。
限制
- 低於 12.2 LTS 的 Databricks Runtime 版本不支援資料列篩選或資料行遮罩。 這些執行階段會安全地失敗,這表示如果您嘗試從這些執行階段的不支援版本中存取資料表,則不會傳回任何資料。
- Delta Sharing 不適用於資料列層級安全性或資料行遮罩。
- 您無法將資料列層級安全性或資料行遮罩套用至檢視。
- 時間旅行不適用於資料列層級安全性或資料行遮罩。
- 不支援對具有原則之資料表中檔案的路徑型存取。
- 不支援對原始原則具有循環相依性的資料列篩選或資料行遮罩原則。
- 不支援深層和淺層複製。
MERGE
陳述式不支援具有資料列篩選原則的資料表,包含巢狀項目、彙總、視窗、限制或非確定性函式。- 不支援 Delta Lake API。
單一用戶計算限制
您無法從 Databricks Runtime 15.3 或以下的單一使用者計算資源存取具有數據列篩選或數據行遮罩的數據表。 如果您的 工作區已啟用無伺服器計算,您可以在 Databricks Runtime 15.4 LTS 或更新版本上使用單一使用者存取模式。 如需詳細資訊,請參閱 單一用戶計算的精細訪問控制。