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 侧管理标签型权限。

相关文档

权限与安全

其他迁移实战

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