使用數據列篩選和數據行遮罩來篩選敏感數據
本文提供使用數據列篩選、數據行遮罩和對應數據表來篩選數據表中敏感數據的指引和範例。 這些功能需要 Unity 目錄。
什麼是資料列篩選?
數據列篩選可讓您將篩選套用至數據表,讓查詢只傳回符合篩選準則的數據列。 您會將資料列篩選實作為 SQL 使用者定義的函式 (UDF)。 Python 和 Scala UDF 也受到支援,但前提是它們裝合在 SQL UDF 中。
什麼是欄遮罩?
欄位遮罩允許您將遮罩函式套用至表格的欄位。 遮罩函式會在查詢執行時進行評估,並將目標欄位的每個參考以遮罩函式的結果替換。 針對大多數的使用情境,資料欄遮罩會根據呼叫用戶的身分來決定是否傳回原始資料欄值,或遮蔽該值。 欄位遮罩是運算式,這些運算式可以直接編寫成 SQL UDF,也可以將 Python 或 Scala UDF 包裝在 SQL UDF 中。
每個表格欄位只能套用一個遮罩函式。 遮罩函式會接受數據行的未遮罩值做為輸入,並傳回遮罩值作為結果。 遮罩函式的傳回值應該與遮罩的數據行相同。 遮罩函式也可以採用其他數據行作為輸入參數,並在遮罩邏輯中使用那些數據行。
這些篩選和動態檢視之間的差異為何?
動態檢視、數據列篩選和數據行遮罩全都可讓您將複雜的邏輯套用至數據表,並在查詢運行時間處理其篩選決策。
動態檢視 是一或多個源數據表的抽象只讀檢視。 用戶可以存取動態檢視,而不需要直接存取源數據表。 建立動態檢視會定義新的數據表名稱,該名稱不得符合存在於相同架構中的任何源數據表或其他數據表和檢視表的名稱。
另一方面,將數據列篩選或數據行遮罩關聯至目標數據表,會將對應的邏輯直接套用至數據表本身,而不需要引進新的數據表名稱。 後續查詢可以使用其原始名稱,繼續直接參考目標數據表。
若您需要將轉換邏輯(例如篩選和遮罩)套用至唯讀表格,並且用戶可以接受以不同名稱引用動態檢視,請使用動態檢視。 如果您想要使用差異共享來篩選數據,則必須使用動態檢視。 如果您想篩選或計算特定數據上的表達式,但仍提供使用者以其原來名稱存取數據表,請使用行篩選和列遮罩。
開始之前
若要將資料列篩選和數據行遮罩新增至數據表,您必須具有:
- 已啟用 Unity 目錄的工作區。
- 在 Unity 目錄中註冊的函式。 此函數可以是 SQL UDF,或是在 Unity Catalog 中註冊的 Python 或 Scala UDF,並包裝在 SQL UDF 中。 如需詳細資訊,請參閱 什麼是使用者定義函式 (UDF)?、Column mask 子句和 ROW FILTER 子句。
也必須滿足下列需求:
- 若要指派將數據列篩選或數據行遮罩加入數據表的函式,您必須具有函式的
EXECUTE
許可權、架構上的USE SCHEMA
,以及父目錄上的USE CATALOG
。 - 如果您在建立 新的 數據表時新增篩選或遮罩,則必須具有架構的
CREATE TABLE
許可權。 - 如果您要將篩選或遮罩新增至 現有的 數據表,您必須是數據表擁有者。
若要存取具有數據列篩選或數據行遮罩的數據表,您的計算資源必須符合下列其中一項需求:
SQL 倉儲。
Databricks Runtime 12.2 LTS 或更高版本中的共用存取模式。
Databricks Runtime 15.4 LTS 或更新版本上的單一使用者存取模式。
您無法在 Databricks Runtime 15.3 或更低版本中,使用以單一使用者存取模式設定的計算來讀取列篩選或資料行遮罩。
若要利用 Databricks Runtime 15.4 LTS 和更新版本所提供的數據篩選,您也必須確認 您的工作區已啟用無伺服器計算,因為支援數據列篩選和數據行遮罩的數據篩選功能會在無伺服器計算上執行。 當您使用配置為單一使用者存取模式的計算來讀取使用行篩選或列遮罩的數據表時,您可能會被收取無伺服器計算資源的費用。 請參閱 單一用戶計算的細微訪問控制。
套用資料列篩選
若要建立數據列篩選,您可以撰寫函式 (UDF)來定義篩選原則,然後將它套用至數據表。 每個數據表只能有一個數據列篩選。 數據列篩選會接受零個或多個輸入參數,其中每個輸入參數都會系結至對應數據表的一個數據行。
您可以使用目錄總管或 SQL 命令來套用資料列篩選。 目錄總管指示假設您已建立函式,並在 Unity 目錄中註冊。 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 使用者定義的函式,它可套用至區域 admin
中群組 US
的成員。
當這個範例函式套用至 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 目錄中註冊。 SQL 指示包含建立數據行遮罩函式,並將其套用至數據表數據行的範例。
目錄瀏覽器
- 在 Azure Databricks 工作區中,按一下
目錄。
- 流覽或搜尋表格。
- 在 [概觀] 索引標籤上,找到您想要套用列遮罩的行,然後點擊 [
遮罩 編輯圖示]。
- 在 [新增欄位遮罩] 對話框中,選取包含篩選函式的目錄及結構,然後選取函式。
- 在展開的對話方塊中,檢視函式定義。 如果函式除了要遮罩的數據行之外,還包含任何參數,請選取您要在其中轉換這些其他函式參數的數據表數據行。
- 按一下新增。
若要從資料表中移除資料行遮罩,請在資料表的資料列中按 fx 資料行遮罩,然後按 移除。
SQL
若要建立數據行遮罩並將它新增至現有的數據表數據行,請使用 CREATE FUNCTION
,並使用 ALTER TABLE
套用遮罩函式。 當您使用 CREATE TABLE
建立數據表時,也可以套用函式。
使用 SET MASK
來套用遮罩函式。 在 MASK
子句中,可以使用任何 Azure Databricks 內建執行階段函式,或呼叫其他使用者定義的函式。 常見的使用案例包括使用 current_user( )
來檢查執行該函式的叫用使用者的身分,或使用 is_account_group_member( )
來取得他們所屬的群組。 如需詳細資訊,請參閱 Column mask 子句 和 內建函式。
建立資料行遮罩:
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');
現在,如果數據列中所有數據行的值小於五或叫用使用者是上述對應數據表的成員,請建立傳回 true
的 SQL UDF。
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 用於受控和外部數據表。
- 在 Unity 目錄中,使用 Lakehouse Federation註冊的多種外部表格的其他數據格式。
原則參數可以包含常數表達式(字串、數值、間隔、布爾值、Null)。
如果 SQL、Python 和 Scala UDF 已在 Unity 目錄中註冊,則支援它們作為數據列篩選或數據行遮罩函式。 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 執行時間版本不支援資料列篩選或數據行遮罩。 這些運行時間會安全地失敗,這表示如果您嘗試從這些運行時間不支援的版本存取數據表,則不會傳回任何數據。
- Delta Sharing 不適用於資料列層級安全性或資料行遮罩。
- 您無法將行層級安全性或資料行遮罩套用至檢視。
- 時間旅行不適用於資料行層級安全性或資料列遮罩。
- 不支援對具有原則之數據表中檔案的路徑型存取。
- 不支援具有循環依賴回到原始政策的列篩選或行掩碼政策。
- 不支援深層和淺層複製。
-
MERGE
指令不支援具備資料列篩選或資料欄遮罩政策的資料表,如果這些政策中包含巢狀結構、聚合、視窗、限制或非確定性函數。 - 不支援 Delta Lake API。
單一用戶計算限制
您無法從 Databricks Runtime 15.3 或以下的單一使用者計算資源存取具有數據列篩選或數據行遮罩的數據表。 如果您的 工作區已啟用無伺服器計算,您可以在 Databricks Runtime 15.4 LTS 或更新版本上使用單一使用者存取模式。 如需詳細資訊,請參閱 單一用戶計算的精細訪問控制。