4. Unity Catalog元数据与权限模型

Unity Catalog 的权限体系建立在一条清晰的三层命名空间之上:catalog.schema.object。所有可授权对象都挂在这棵树上,权限沿树自上而下继承。理解这一点,是掌握 GRANT/REVOKE 与继承规则的前提。

命名空间中的对象分为两类:容器对象(Catalog、Schema)和数据/逻辑对象(Table、View、Volume、Function)。容器对象本身不存数据,但它们的权限会向下传递;数据对象是权限真正生效的终点。此外还有一类元数据对象(如 Metastore、External Location、Storage Credential),它们不在三层命名空间内,但控制着数据落地的物理边界。

Metastore(元数据顶层) External Location · Storage Credential Catalog:prod_catalog USE CATALOG · CREATE SCHEMA · MANAGE Schema:sales_schema USE SCHEMA · CREATE TABLE/VIEW/VOLUME/FUNCTION · MANAGE Table SELECT · MODIFY CREATE · ALL PRIVILEGES 行/列级过滤可叠加 View SELECT · MODIFY ALL PRIVILEGES 默认以所有者权限执行 Volume READ VOLUME WRITE VOLUME 管理非结构化文件 Function EXECUTE ALL PRIVILEGES UDF / 自定义逻辑 继承规则要点 ① 父级授权自动向下继承:在 Catalog 授予 USE CATALOG,其下所有 Schema 均可被引用。 ② 子级授权不回传父级:在 Table 授予 SELECT,不会让该用户获得 Schema 的 USE SCHEMA。 ③ 访问对象需同时具备路径上各级权限:读表 = USE CATALOG + USE SCHEMA + SELECT。 ④ REVOKE 只撤销本级授权,不自动清除子级已单独授予的权限。

一、层级权限的继承方向

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 或权限拒绝。这是初学者最常踩的坑:以为给了表权限就能查,实际上路径上的容器权限也必须显式授予。

二、各对象的权限清单与语义差异

不同对象支持的权限集并不相同,理解它们的语义差异比死记清单更重要。

对象核心权限语义说明
CatalogUSE CATALOG、CREATE SCHEMA、MANAGEUSE 是"进入"资格;CREATE SCHEMA 允许建库;MANAGE 可转授权
SchemaUSE SCHEMA、CREATE TABLE/VIEW/VOLUME/FUNCTION、MANAGEUSE 是"进入"资格;CREATE 系列按对象类型细分
TableSELECT、MODIFY、ALL PRIVILEGESMODIFY 含 INSERT/UPDATE/DELETE;可叠加行/列级过滤
ViewSELECT、MODIFY、ALL PRIVILEGES默认以视图所有者权限执行,可做权限收敛
VolumeREAD VOLUME、WRITE VOLUME管理非结构化文件,读写分离
FunctionEXECUTE、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(若环境支持)。

常见误区:认为撤销父级权限会自动清理所有子级授权。实际上 Unity Catalog 的授权是独立记录,REVOKE 不会级联删除下游授权。在人员变动或项目下线时,务必用 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 的数据共享,都只是在这套基础模型上的扩展。