Databricks Unity Catalog → Lakehouse 迁移实战:权限与治理

如果你的数据平台用 Databricks Unity Catalog 管理权限——RBAC 角色、列级脱敏、行级访问控制、数据审计——迁移到 ClickZetta Lakehouse 的工作量比你想象的低。GRANT/REVOKE 语法完全一致,角色管理一字不改,

SET MASK
SET MASK
关键字相同。改动集中在 3 处:去掉 catalog 前缀(三级 → 两级命名)、脱敏函数里换一个 API(
is_account_group_member
is_account_group_member
array_contains(current_roles(),...)
array_contains(current_roles(),...)
)、行级安全从声明式 ROW FILTER 改为显式安全视图。

本文用一个金融支付场景验证这一点:含 PII 字段(email/phone/card)的用户表、按区域隔离的订单表、余额账户表——完整迁移 RBAC、列脱敏、行级安全、审计日志,经过 16 项自动化验证,全部通过。

完整代码见 GitHub:databricks2lakehouse-governance


原始项目

演示数据为金融支付场景,包含 3 张表:

行数敏感字段访问控制需求
users
users
100
email
email
phone
phone
ssn_last4
ssn_last4
脱敏:非 admin 看掩码值
orders
orders
300
amount
amount
region
region
行级:analyst 只看 North America
accounts
accounts
50
balance
balance
card_number
card_number
脱敏:card 末 4 位可见

迁移后的代码在

03_lakehouse/sql/
03_lakehouse/sql/
目录(6 个 SQL 文件),可与
01_source/sql/
01_source/sql/
(原始 UC SQL)逐文件对照。

结论先行

大部分权限 SQL 直接复用,改动极少,甚至为零

改动项工作量说明
脱敏函数判断 API极低
is_account_group_member('g')
is_account_group_member('g')
array_contains(current_roles(), 'ws.g')
array_contains(current_roles(), 'ws.g')
审计表名及列名
system.access.audit
system.access.audit
sys.information_schema.job_history
sys.information_schema.job_history
,列名不同

完全不需要改

CREATE ROLE
CREATE ROLE
GRANT SELECT
GRANT SELECT
GRANT ALL PRIVILEGES
GRANT ALL PRIVILEGES
WITH GRANT OPTION
WITH GRANT OPTION
SHOW GRANTS
SHOW GRANTS
SET MASK
SET MASK
SET ROW FILTER
SET ROW FILTER
三级命名(workspace.schema.table)——语法完全一致。行级安全是零改动迁移!

Lakehouse 还有 UC 没有的额外能力:

mask_inner
mask_inner
/
mask_outer
mask_outer
(字符串脱敏内置函数)、
AI_MASK
AI_MASK
(大模型语义脱敏)、
CREATE SHARE
CREATE SHARE
(数据共享,SQL DDL 比 Delta Sharing 更简洁)。


技术栈对比

Databricks Unity CatalogClickZetta Lakehouse
命名空间层级三级:
catalog.schema.table
catalog.schema.table
三级:
workspace.schema.table
workspace.schema.table
(结构相同)
角色管理
CREATE ROLE
CREATE ROLE
(metastore 级)
CREATE ROLE
CREATE ROLE
(workspace 级)
GRANT 语法
GRANT ... ON TABLE cat.s.t TO ROLE r
GRANT ... ON TABLE cat.s.t TO ROLE r
GRANT ... ON TABLE s.t TO ROLE r
GRANT ... ON TABLE s.t TO ROLE r
列脱敏判断
is_account_group_member('group')
is_account_group_member('group')
array_contains(current_roles(), 'ws.role')
array_contains(current_roles(), 'ws.role')
列脱敏应用
ALTER TABLE ... ALTER COLUMN c SET MASK f
ALTER TABLE ... ALTER COLUMN c SET MASK f
ALTER TABLE ... ALTER COLUMN c SET MASK f
ALTER TABLE ... ALTER COLUMN c SET MASK f
行级安全
ALTER TABLE ... SET ROW FILTER f ON (col)
ALTER TABLE ... SET ROW FILTER f ON (col)
ALTER TABLE ... SET ROW FILTER f ON (col)
ALTER TABLE ... SET ROW FILTER f ON (col)
数据共享Delta Sharing(UC + REST API)
CREATE SHARE
CREATE SHARE
/
GRANT select, read metadata ... TO SHARE
GRANT select, read metadata ... TO SHARE
字符串脱敏手写 REGEXP_REPLACE
mask_inner()
mask_inner()
/
mask_outer()
mask_outer()
(内置函数)
AI 智能脱敏
AI_MASK()
AI_MASK()
(Lakehouse 独有)
Tag / ABACUC Tag 策略(跨表打标签)暂不支持 → 用角色命名 + Schema 隔离替代
审计来源
system.access.audit
system.access.audit
(account 级)
sys.information_schema.job_history
sys.information_schema.job_history
(workspace 级)


项目背景

三张表覆盖典型金融场景:

  • users
    users
    :用户注册信息,含 email/phone/ssn_last4 等 PII,需列级脱敏
  • orders
    orders
    :销售订单,按 region 字段划分北美/欧洲/亚太,需行级隔离
  • accounts
    accounts
    :账户余额和银行卡信息,balance 和 card_number 高度敏感

原始 UC 设计了 3 个角色:

  • payments_admin
    payments_admin
    :看全量真实数据
  • payments_analyst
    payments_analyst
    :脱敏数据 + 仅看 North America 订单
  • payments_viewer
    payments_viewer
    :脱敏数据 + 仅看 Asia 订单

迁移步骤

第一步:去掉 catalog 前缀

UC 用三级命名,Lakehouse workspace 本身就是 catalog 的边界,只需两级:

-- UC(三级) GRANT SELECT ON TABLE payments_catalog.raw.orders TO ROLE payments_analyst; -- Lakehouse(两级)— 去掉 catalog 前缀 GRANT SELECT ON TABLE gov_raw.orders TO ROLE payments_analyst;

第二步:RBAC — 语法完全一致

GRANT/REVOKE/SHOW GRANTS 语法零改动:

-- 两边完全相同 CREATE ROLE IF NOT EXISTS payments_analyst; CREATE ROLE IF NOT EXISTS payments_admin; GRANT SELECT ON TABLE gov_raw.orders TO ROLE payments_analyst; GRANT ALL PRIVILEGES ON SCHEMA gov_raw TO ROLE payments_admin; GRANT SELECT ON ALL TABLES IN SCHEMA gov_raw TO ROLE payments_viewer; GRANT SELECT ON TABLE gov_raw.users TO ROLE payments_admin WITH GRANT OPTION; SHOW GRANTS TO ROLE payments_analyst;

第三步:列脱敏 —
SET MASK
SET MASK
相同,函数 API 改一处

UC 用

is_account_group_member()
is_account_group_member()
,Lakehouse 用
array_contains(current_roles(), 'workspace.role')
array_contains(current_roles(), 'workspace.role')

# UC 脱敏函数 CREATE FUNCTION payments_catalog.raw.mask_email(email STRING) RETURN CASE WHEN is_account_group_member('payments_admin') THEN email ELSE CONCAT(LEFT(email, 2), '***@***.***') END;

-- Lakehouse 脱敏函数(只改判断 API,逻辑一致) CREATE OR REPLACE FUNCTION gov_raw.mask_email(email STRING) RETURNS STRING RETURN CASE WHEN array_contains(current_roles(), 'quick_start.payments_admin') -- ← current_roles() OR array_contains(current_roles(), 'workspace_admin') THEN email ELSE CONCAT(LEFT(email, 2), '***@***.***') END; -- SET MASK 应用语法完全相同 ALTER TABLE gov_raw.users ALTER COLUMN email SET MASK gov_raw.mask_email; ALTER TABLE gov_raw.users ALTER COLUMN phone SET MASK gov_raw.mask_phone; ALTER TABLE gov_raw.accounts ALTER COLUMN card_number SET MASK gov_raw.mask_card;

实测脱敏效果(非 admin 用户看到):

字段原始值脱敏后
email
user001@example.com
user001@example.com
u***@***.***
u***@***.***
phone
+12345678901
+12345678901
****8901
****8901
card_number
4866524041574
4866524041574
****-****-****-1574
****-****-****-1574

第四步:行级安全 —
SET ROW FILTER
SET ROW FILTER
语法完全一致

Lakehouse 原生支持

SET ROW FILTER
SET ROW FILTER
,与 UC 语法完全一致,零改动

-- UC(Databricks) CREATE FUNCTION payments_catalog.raw.filter_orders_by_region(region STRING) RETURN CASE WHEN is_account_group_member('payments_admin') THEN TRUE WHEN is_account_group_member('payments_analyst') AND region = 'North America' THEN TRUE ELSE FALSE END; ALTER TABLE payments_catalog.raw.orders SET ROW FILTER payments_catalog.raw.filter_orders_by_region ON (region);

-- Lakehouse — 语法完全一致,只改函数体里的 is_account_group_member CREATE OR REPLACE FUNCTION gov_raw.filter_orders_by_role(region STRING) RETURNS BOOLEAN AS array_contains(current_roles(), 'quick_start.payments_admin') OR array_contains(current_roles(), 'workspace_admin') OR (array_contains(current_roles(), 'quick_start.payments_analyst') AND region = 'North America') OR (array_contains(current_roles(), 'quick_start.payments_viewer') AND region = 'Asia'); -- SET ROW FILTER 语法完全相同 ALTER TABLE gov_raw.orders SET ROW FILTER gov_raw.filter_orders_by_role ON (region); -- 验证绑定 DESC EXTENDED gov_raw.orders; -- 输出末尾显示 # Row Filter 段 -- 移除 ALTER TABLE gov_raw.orders DROP ROW FILTER;

ROW FILTER 对 SELECT、COUNT、UPDATE、DELETE 全面生效——当前用户(workspace_admin)查询 300 行,如果是

payments_analyst
payments_analyst
角色则只看到 North America 的 52 行。

第五步:审计 — 表名和列名适配

UC 用

system.access.audit
system.access.audit
(account 级),Lakehouse 用
sys.information_schema.job_history
sys.information_schema.job_history
(workspace 级):

-- UC 审计 SELECT event_time, user_name, action_name, request_params FROM system.access.audit WHERE event_time >= current_timestamp() - INTERVAL 7 DAYS AND action_name IN ('createTable','grantPermission','revokePermission');

-- Lakehouse 审计(列名不同,日期用字面量字符串) SELECT job_type, job_creator, -- UC: user_name LEFT(job_text, 100) AS sql_preview, -- UC: request_params status, LEFT(start_time, 19) AS time FROM sys.information_schema.job_history WHERE start_time >= '2026-06-07' -- 必须字面量,不能用 NOW() - INTERVAL AND (UPPER(job_text) LIKE 'GRANT%' OR UPPER(job_text) LIKE 'REVOKE%' OR UPPER(job_text) LIKE 'CREATE TABLE%') ORDER BY start_time DESC;


数据共享(Data Sharing)

Lakehouse 的 Share 对标 Databricks Delta Sharing——将表或视图共享给其他工作空间或外部消费方,语法与 UC 高度相近:

-- Step 1: 创建 Share 对象 CREATE SHARE IF NOT EXISTS analytics_share COMMENT 'Analytics data share for partners'; -- Step 2: 将表/视图加入 Share(双权限:select + read metadata) GRANT select, read metadata ON VIEW gov_marts.orders_by_region TO SHARE analytics_share; GRANT select, read metadata ON TABLE gov_raw.orders TO SHARE analytics_share; -- 批量加入 Schema 下所有表 GRANT SELECT, READ METADATA ON ALL TABLES IN SCHEMA gov_raw TO SHARE analytics_share; -- Step 3: 查看 Share 内容 DESC SHARE analytics_share; -- Step 4: 消费方接入 CREATE SCHEMA partner_schema FROM SHARE analytics_share;

SELECT, READ METADATA
SELECT, READ METADATA
双权限组合:
select
select
允许查询数据,
read metadata
read metadata
让消费方能发现表/视图的存在。两者通常一起授予。UC Delta Sharing 的配置通过 Databricks UI/REST API 完成;Lakehouse Share 直接用 SQL DDL,更简洁。


Lakehouse 独有能力

mask_inner
mask_inner
/
mask_outer
mask_outer
:字符串脱敏函数,UC 没有,不需要 AI 连接,直接在脱敏函数里使用:

-- mask_inner:掩盖中间字符(保留前 n 位和后 m 位) SELECT mask_inner('user001@example.com', 2, 7); -- → usXXXXXXXXXXXXX.com(保留前2、后7,中间掩盖) -- mask_outer:掩盖两端字符 SELECT mask_outer('+12345678901', 1, 4); -- → X1234567XXXX -- 用在脱敏函数里比手写 CONCAT+REGEXP_REPLACE 更简洁 CREATE OR REPLACE FUNCTION gov_raw.mask_email_v2(email STRING) RETURNS STRING RETURN CASE WHEN array_contains(current_roles(), 'quick_start.payments_admin') THEN email ELSE mask_inner(email, 2, 7) END;

AI_MASK
AI_MASK
:基于大模型的语义脱敏,自动识别 PII 类型(姓名、手机、身份证等),UC 无对应能力:

-- 需要配置 AI 连接(百炼/通义等模型) SELECT AI_MASK('conn_bailian:qwen3.5-plus', '用户王小明,手机号:13800138000', ARRAY('姓名', '手机号')); -- → '用户***,手机号:138****8000'


注意事项

在 AWS 新加坡实例(

aws_singapore_prod
aws_singapore_prod
)实测,16/16 全部通过:

检查项期望值结果
gov_raw.users100
gov_raw.orders300
gov_raw.accounts50
analyst 有 GRANT 记录≥2
admin 有 GRANT 记录≥1
viewer 有 GRANT 记录≥1
email 已脱敏True
phone 已脱敏True
card_number 已脱敏True
mask_email 函数存在True
mask_phone 函数存在True
mask_card 函数存在True
orders_by_region admin 看 300 行300
orders_analyst_view 只看 North America52
analyst_view 只有 1 个 region1
job_history 有记录≥1

注意事项

  • current_roles()
    current_roles()
    含 workspace 前缀
    :Lakehouse 的
    current_roles()
    current_roles()
    返回的角色名带 workspace 前缀(如
    quick_start.payments_admin
    quick_start.payments_admin
    ),匹配时必须带完整前缀,不能只写
    payments_admin
    payments_admin
  • SET MASK
    SET MASK
    在表重建后失效
    :DROP TABLE 再 CREATE 后,列掩码不会自动继承,需要重新
    ALTER TABLE ... ALTER COLUMN c SET MASK
    ALTER TABLE ... ALTER COLUMN c SET MASK
  • COPY INTO 类型推断:外部 Volume 的 COPY INTO 不支持
    inferSchema
    inferSchema
    ,建表时必须显式声明字段类型(尤其 phone/card 要用 STRING,否则被推断为 BIGINT 导致数据丢失)。
  • job_history 日期条件
    WHERE start_time >= '2026-06-07'
    WHERE start_time >= '2026-06-07'
    必须是字面量字符串,不支持
    CURRENT_DATE()
    CURRENT_DATE()
    INTERVAL
    INTERVAL
    表达式。
  • 行级安全函数判断 API:ROW FILTER 函数体里同样需要把
    is_account_group_member('g')
    is_account_group_member('g')
    改成
    array_contains(current_roles(), 'ws.g')
    array_contains(current_roles(), 'ws.g')
    ,这是唯一的改动点。
    ALTER TABLE ... SET ROW FILTER
    ALTER TABLE ... SET ROW FILTER
    /
    DROP ROW FILTER
    DROP ROW FILTER
    语法完全相同。
  • Tag / ABAC(诚实边界):UC 支持基于 Tag 的细粒度访问控制(ABAC),通过给表/列打标签再写策略实现。Lakehouse 目前不支持 Tag 驱动的 ABAC,建议用角色命名规范(如
    dept_finance_analyst
    dept_finance_analyst
    )+ Schema 隔离模拟 ABAC 效果,或保留 Databricks 侧管理标签型权限。

相关文档

权限与安全

其他迁移实战

联系我们
预约咨询
微信咨询
电话咨询
邮件咨询