4. Unity Catalog元存储与数据对象模型
Unity Catalog 的访问控制之所以能做到“一处授权、处处生效”,根本原因在于它把数据资产组织成了一棵全局统一的命名空间树。理解这棵树的结构,是理解后续所有权限模型、跨工作区共享、血缘追踪的前提。本节围绕元存储(Metastore)、目录(Catalog)、模式(Schema)、表(Table)、视图(View)、卷(Volume)、函数(Function)与模型(Model)这八类对象,讲清它们的层级关系、命名规则以及各自承担的角色。
一、三层命名空间:从元存储到模式
Unity Catalog 采用“三层命名空间”(three-level namespace)来唯一标识一个数据对象,格式为:
catalog.schema.object
例如:sales_prod.orders.fact_order
sales_prod.orders.v_order_summary
sales_prod.raw_files.landing_zone
这三层分别是:目录(Catalog)、模式(Schema)、对象(Object)。目录是命名空间的第一层,通常按业务域、环境或团队划分,例如 sales_prod、sales_dev、hr_prod。模式是第二层,用于在目录内部进一步分组,例如 orders、customers、raw_files。第三层则是具体的表、视图、卷、函数或模型。
需要特别注意的是,元存储(Metastore)本身不是三层命名空间的一部分。元存储是账户级别的顶层容器,一个元存储可以挂载到多个工作区,但一个工作区在同一时刻只能绑定一个元存储。元存储负责存储所有目录的元数据、权限定义、血缘信息以及存储凭证。换句话说,元存储是“根”,目录是“根下的第一级分支”,而 catalog.schema.object 是用户日常引用对象时使用的完整路径。
main 或 hive_metastore)。生产环境中建议始终写全三层名称,避免因默认值变化导致误操作。二、八类对象的层级与职责
下面这张图展示了 Unity Catalog 中元存储、目录、模式与各类数据对象之间的层级关系,以及它们各自承载的核心职责。
从图中可以看到,元存储位于最顶层,向下依次是目录、模式,最后是具体对象。每个目录下可以创建多个模式,每个模式下可以创建表、视图、卷、函数和模型。这种严格的层级结构使得权限可以沿着树向下继承:在目录级别授予的权限会自动应用到该目录下所有模式及其对象;在模式级别授予的权限则只作用于该模式内部。
三、各类对象的特性与使用场景
表(Table)是 Unity Catalog 中最常见的对象,底层通常由 Delta Lake 格式存储。表分为托管表(Managed Table)和外部表(External Table)。托管表的数据和元数据都由 Unity Catalog 管理,删除表时数据一并删除;外部表的数据存放在外部存储路径,删除表只删除元数据,数据保留。创建托管表的示例:
CREATE TABLE sales_prod.orders.fact_order (
order_id BIGINT,
customer_id BIGINT,
amount DECIMAL(12,2),
order_date DATE
)
USING DELTA
COMMENT '订单事实表';
视图(View)是只读的虚拟表,基于一个或多个底层表定义查询逻辑。视图本身不存储数据,但视图定义会持久化在元存储中。视图常用于简化复杂查询、限制列级访问或对敏感字段做脱敏处理。例如,可以创建一个只暴露非敏感列的视图,然后把该视图的 SELECT 权限授予分析团队,而底层表的访问权限保持收紧。
卷(Volume)是 Unity Catalog 中用于管理非结构化数据的对象,例如 CSV 文件、JSON 日志、图片、模型权重文件等。卷分为托管卷和外部卷,分别对应由 Unity Catalog 管理存储路径和指向外部路径两种模式。卷的引入解决了过去非结构化文件只能通过 DBFS 路径访问、难以统一授权的问题。引用卷内文件的路径格式为:
/Volumes/sales_prod/raw_files/landing_zone/2024/orders.csv
函数(Function)允许用户将自定义逻辑注册到 Unity Catalog 中,供 SQL 或 PySpark 调用。函数可以是用 SQL 编写的,也可以是 Python 函数。函数同样遵循三层命名空间,权限控制与表一致。例如,可以创建一个用于计算客户等级的函数,并只授予特定团队 EXECUTE 权限。
模型(Model)是 Unity Catalog 中对机器学习模型的注册与管理能力。模型以版本(Version)为单位进行管理,每个版本对应一次注册。模型可以被打上别名(Alias),例如 champion 或 challenger,用于在推理时引用特定版本。模型对象同样支持权限控制,可以限制哪些用户或组能够读取、修改或部署模型。
四、命名规范与最佳实践
在实际项目中,命名规范直接影响权限管理的可维护性。以下是一套经过验证的命名建议:
- 目录命名:采用
业务域_环境的格式,例如sales_prod、sales_dev、hr_prod。避免使用default或main作为生产目录名。 - 模式命名:按数据分层或功能划分,例如
raw(原始层)、cleansed(清洗层)、curated(汇总层)、sandbox(沙箱)。 - 表命名:使用小写字母和下划线,采用
事实_维度或业务实体的命名方式,例如fact_order、dim_customer。 - 视图命名:以
v_前缀标识,例如v_order_summary。 - 卷命名:以
vol_或用途命名,例如landing_zone、model_artifacts。
五、权限继承与对象层级的关系
理解对象层级之后,权限继承就变得直观了。Unity Catalog 的权限模型遵循“父级授权、子级继承”的原则。例如,在目录 sales_prod 上授予 USE CATALOG 权限,用户就能看到该目录;在模式 orders 上授予 USE SCHEMA 权限,用户就能访问该模式下的对象;在表 fact_order 上授予 SELECT 权限,用户才能查询该表。这三层权限缺一不可——只有同时具备目录的 USE、模式的 USE 和表的 SELECT,用户才能真正读取数据。
这种设计的好处是权限可以批量管理。例如,新入职的数据分析师只需要加入 analysts 组,而该组已经在 sales_prod 目录和 orders 模式上被授予了 USE 权限,那么分析师立刻就能访问该模式下所有已授权表,无需逐表配置。当组织规模扩大、数据资产增多时,这种基于层级的权限继承能显著降低管理成本。
最后需要强调的是,元存储虽然是顶层容器,但它本身不直接参与三层命名空间的引用。用户在日常 SQL 或代码中写的是 catalog.schema.object,而元存储负责的是“这个目录属于哪个账户、绑定哪些工作区、使用什么存储凭证”这类账户级治理问题。把元存储理解为“根节点”和“治理边界”,把目录、模式、对象理解为“数据资产的命名空间树”,就能准确把握 Unity Catalog 对象模型的全貌。