创建动态试图

在 Unity Catalog 中,可以使用动态视图配置细粒度访问控制,包括:

  • 列或行级别的安全性。
  • 数据掩码。

Unity Catalog 引入了以下功能,这些功能允许你动态限制哪些用户可以访问视图中的行、列或记录:

  • current_user():返回当前用户的电子邮件地址。
  • is_account_group_member():如果当前用户是特定帐户级别组的成员,则返回 TRUE。 建议在针对 Unity Catalog 数据的动态视图中使用。
  • is_member():如果当前用户是特定工作区级别组的成员,则返回 TRUE。 提供此函数是为了与现有 Hive 元存储兼容。 请避免将它与针对 Unity Catalog 数据的视图一起使用,因为它不评估帐户级别的组成员身份。

Azure Databricks 建议不要授予用户读取视图中引用的表和视图的权限。

下面的示例说明如何在 Unity Catalog 中创建动态视图。

开始之前

若要创建或读取动态视图,要求与标准视图的要求相同,但计算要求除外。 必须使用以下计算资源之一:

  • SQL 仓库。

  • 具有共享访问模式的计算。

  • 在 Databricks Runtime 15.4 LTS 或更高版本上(公共预览版)具有单用户访问模式的计算。

    无法在 Databricks Runtime 15.3 或更低版本上使用单用户计算读取动态视图。

    若要利用 Databricks Runtime 15.4 LTS 及更高版本中提供的数据筛选,你还必须验证你的工作区是否已启用无服务器计算,因为支持动态视图的数据筛选功能在无服务器计算上运行。 因此,当你使用单用户计算读取动态视图时,可能需要支付无服务器计算资源的费用。 请参阅单用户计算上的精细访问控制

列级权限

使用动态视图,可以限制特定用户或组可以访问的列。 在下面的示例中,只有 auditors 组的成员可以从 sales_raw 表中访问电子邮件地址。 在查询分析过程中,Apache Spark 将 CASE 语句替换为文字字符串 REDACTED 或替换为电子邮件地址列的实际内容。 其他列按正常方式返回。 此策略对查询性能没有负面影响。

-- Alias the field 'email' to itself (as 'email') to prevent the
-- permission logic from showing up directly in the column name results.
CREATE VIEW sales_redacted AS
SELECT
  user_id,
  CASE WHEN
    is_account_group_member('auditors') THEN email
    ELSE 'REDACTED'
  END AS email,
  country,
  product,
  total
FROM sales_raw

行级权限

使用动态视图,你可以指定低至行级或字段级的权限。 在下面的示例中,当交易金额超过 1,000,000 美元时,只有 managers 组的成员才能查看交易金额。 对于其他用户,匹配结果将被筛选掉。

CREATE VIEW sales_redacted AS
SELECT
  user_id,
  country,
  product,
  total
FROM sales_raw
WHERE
  CASE
    WHEN is_account_group_member('managers') THEN TRUE
    ELSE total <= 1000000
  END;

数据屏蔽

因为 Unity Catalog 中的视图使用 Spark SQL,所以可以通过使用更复杂的 SQL 表达式和正则表达式来实现高级数据屏蔽。 在下面的示例中,所有用户都可以分析电子邮件域,但只有 auditors 组的成员才能查看用户的整个电子邮件地址。

-- The regexp_extract function takes an email address such as
-- user.x.lastname@example.com and extracts 'example', allowing
-- analysts to query the domain name.

CREATE VIEW sales_redacted AS
SELECT
  user_id,
  region,
  CASE
    WHEN is_account_group_member('auditors') THEN email
    ELSE regexp_extract(email, '^.*@(.*)$', 1)
  END
  FROM sales_raw