4. Unity Catalog元数据与权限模型
Unity Catalog 的权限体系建立在一条清晰的三层命名空间之上:catalog.schema.object。所有可授权对象都挂在这棵树上,权限沿树自上而下继承。理解这一点,是掌握 GRANT/REVOKE 与继承规则的前提。
命名空间中的对象分为两类:容器对象(Catalog、Schema)和数据/逻辑对象(Table、View、Volume、Function)。容器对象本身不存数据,但它们的权限会向下传递;数据对象是权限真正生效的终点。此外还有一类元数据对象(如 Metastore、External Location、Storage Credential),它们不在三层命名空间内,但控制着数据落地的物理边界。
一、层级权限的继承方向
Unity Catalog 的继承是单向向下的。当你在 prod_catalog 上执行 GRANT USE CATALOG ON CATALOG prod_catalog TO `data_team`,data_team 组就获得了引用该 Catalog 下任意 Schema 的资格。但这只是"资格",并不等于能读数据。要真正查询一张表,用户必须同时满足路径上每一级的权限要求:
-- 读取 prod_catalog.sales_schema.orders 所需的最小权限组合
GRANT USE CATALOG ON CATALOG prod_catalog TO `analyst_group`;
GRANT USE SCHEMA ON SCHEMA prod_catalog.sales_schema TO `analyst_group`;
GRANT SELECT ON TABLE prod_catalog.sales_schema.orders TO `analyst_group`;
三者缺一不可。如果只授予了 SELECT 而缺少 USE SCHEMA,查询会直接报错 SCHEMA_NOT_FOUND 或权限拒绝。这是初学者最常踩的坑:以为给了表权限就能查,实际上路径上的容器权限也必须显式授予。
二、各对象的权限清单与语义差异
不同对象支持的权限集并不相同,理解它们的语义差异比死记清单更重要。
| 对象 | 核心权限 | 语义说明 |
|---|---|---|
| Catalog | USE CATALOG、CREATE SCHEMA、MANAGE | USE 是"进入"资格;CREATE SCHEMA 允许建库;MANAGE 可转授权 |
| Schema | USE SCHEMA、CREATE TABLE/VIEW/VOLUME/FUNCTION、MANAGE | USE 是"进入"资格;CREATE 系列按对象类型细分 |
| Table | SELECT、MODIFY、ALL PRIVILEGES | MODIFY 含 INSERT/UPDATE/DELETE;可叠加行/列级过滤 |
| View | SELECT、MODIFY、ALL PRIVILEGES | 默认以视图所有者权限执行,可做权限收敛 |
| Volume | READ VOLUME、WRITE VOLUME | 管理非结构化文件,读写分离 |
| Function | EXECUTE、ALL PRIVILEGES | 控制 UDF 调用权,不涉及数据本身 |
特别注意 View 的权限收敛特性。假设 orders 表包含敏感列 credit_card,你可以创建一个只暴露非敏感列的视图,然后只把视图的 SELECT 授予分析师组,而不授予底层表的任何权限。由于视图默认以所有者权限执行,分析师通过视图能读到数据,却无法直接访问底层表。这是 Unity Catalog 中实现"最小权限"最常用的手段之一。
三、GRANT / REVOKE 语法与转授权
标准语法结构为:GRANT <privilege> ON <object_type> <object_name> TO <principal>。其中 principal 可以是用户、组或服务主体。关键参数是 WITH GRANT OPTION,它允许被授权者将权限继续转授给他人:
-- 授予并允许转授权
GRANT SELECT ON TABLE prod_catalog.sales_schema.orders
TO `team_lead` WITH GRANT OPTION;
-- 撤销转授权能力(保留 SELECT 本身)
REVOKE GRANT OPTION FOR SELECT
ON TABLE prod_catalog.sales_schema.orders
FROM `team_lead`;
-- 完全撤销
REVOKE SELECT ON TABLE prod_catalog.sales_schema.orders
FROM `team_lead`;
REVOKE 的行为需要特别注意:它只撤销本级授权。如果 team_lead 之前通过 WITH GRANT OPTION 把 SELECT 转授给了 analyst_a,那么撤销 team_lead 的 SELECT 后,analyst_a 的权限不会自动消失——因为 analyst_a 的授权记录是独立存在的。要彻底清理,必须显式撤销 analyst_a 的权限,或使用 REVOKE ... CASCADE(若环境支持)。
SHOW GRANTS 逐级核查。
四、实操:一次完整的权限配置与验证
假设需要让 analyst_group 能够查询 prod_catalog.sales_schema 下的 orders 表,但不能修改,也不能访问同 Schema 下的 hr_salary 表。配置过程如下:
-- 1. 授予路径权限
GRANT USE CATALOG ON CATALOG prod_catalog TO `analyst_group`;
GRANT USE SCHEMA ON SCHEMA prod_catalog.sales_schema TO `analyst_group`;
-- 2. 只授予目标表的 SELECT
GRANT SELECT ON TABLE prod_catalog.sales_schema.orders TO `analyst_group`;
-- 3. 验证授权结果
SHOW GRANTS ON TABLE prod_catalog.sales_schema.orders;
-- 4. 以 analyst_group 成员身份测试
SELECT * FROM prod_catalog.sales_schema.orders LIMIT 10; -- 应成功
SELECT * FROM prod_catalog.sales_schema.hr_salary LIMIT 10; -- 应报权限错误
验证时重点观察两个信号:目标表查询返回数据,非授权表查询抛出 PERMISSION_DENIED 或 TABLE_OR_VIEW_NOT_FOUND。后者是 Unity Catalog 的刻意设计——对无权限对象返回"不存在"而非"无权限",避免泄露对象存在性信息。
五、权限设计的三条实用原则
- 按组授权,不按个人。把权限授予组,人员变动时只需调整组成员,无需逐个 REVOKE/GRANT。
- 容器权限宽授,数据权限窄授。USE CATALOG 和 USE SCHEMA 可以给得宽松,因为它们只控制"能否进入";SELECT/MODIFY 必须按需精确授予。
- 用 View 做权限收敛。当需要暴露部分列或部分行时,优先建视图并只授视图权限,而不是在表上做复杂的列级授权。
掌握这棵三层权限树和继承方向,后续的列级/行级过滤、动态视图、以及跨 Catalog 的数据共享,都只是在这套基础模型上的扩展。