4. 元数据分类与标签体系设计

在Unity Catalog中,元数据治理的起点不是“建多少标签”,而是先回答一个更基础的问题:我们究竟要用标签解决哪些问题。标签体系如果只停留在“给表打几个词”的层面,很快就会退化成无人维护的装饰。真正可用的标签体系,必须能同时支撑四类诉求:业务人员按业务域找数据、数据工程师按数据域做分层建模、安全团队按安全等级做访问控制、运维团队按生命周期做成本与归档管理。因此,本节围绕业务域、数据域、安全等级、生命周期四个核心维度展开,并说明如何在Unity Catalog中把标签与属性真正落地。

一、四个标签维度的定位与取值设计

四个维度不是并列的“分类词”,而是各自承担不同治理职责的坐标系。业务域回答“这份数据服务于谁”,数据域回答“这份数据在数仓中处于什么加工层级”,安全等级回答“谁能看、能看多少”,生命周期回答“这份数据该留多久、放在哪一层存储”。

维度治理职责典型取值示例是否可多值
业务域业务归属与查找入口零售、供应链、金融、营销、客服通常单值,允许主+辅
数据域数仓分层与加工阶段ODS、DWD、DWS、ADS、Feature单值
安全等级访问控制与脱敏策略公开、内部、机密、绝密单值,取最高敏感级别
生命周期保留、归档、成本管理热、温、冷、归档、待删除单值,随状态流转

取值设计要遵循两个原则。第一,枚举封闭:每个维度的取值必须是一份受控词表,不能由用户自由填写,否则“零售”“零售业务”“Retail”会同时出现,标签就失去聚合能力。第二,语义唯一:同一份数据在同一维度上只能有一个权威取值,避免“既是机密又是内部”这类冲突。安全等级尤其如此,应取所有字段中的最高敏感级别作为表级等级。

二、标签与属性的分工

在Unity Catalog中,标签(Tag)和属性(Property/Comment)是两种不同的元数据载体,很多团队会混用。标签是可检索、可策略引用、可跨对象聚合的键值对,适合承载分类维度;属性更多是描述性、说明性的文本,适合承载负责人、SLA、业务口径说明等不适合做枚举的内容。一个实用的分工是:能用受控词表表达的,做成标签;需要自由文本或长描述的,做成属性或注释。

Unity Catalog的标签可以打在Catalog、Schema、Table、Column、View、Volume等对象上。表级标签用于整体分类,列级标签用于精细化的敏感字段标记,两者配合才能支撑列级脱敏与行级过滤。

三、在Unity Catalog中落地标签

落地分三步:定义受控词表、批量打标、用标签驱动策略。下面给出可直接参考的SQL示例。假设我们为零售业务域建立标签体系,先创建标签键,再对表打标。

-- 1. 在Metastore级别创建受控标签键(需Metastore Admin权限)
CREATE TAG IF NOT EXISTS business_domain
  VALUES ('retail','supply_chain','finance','marketing','service');

CREATE TAG IF NOT EXISTS data_layer
  VALUES ('ods','dwd','dws','ads','feature');

CREATE TAG IF NOT EXISTS security_level
  VALUES ('public','internal','confidential','secret');

CREATE TAG IF NOT EXISTS lifecycle_stage
  VALUES ('hot','warm','cold','archive','to_delete');

-- 2. 对表打标(表级)
ALTER TABLE prod.retail.dwd_order_detail
  SET TAGS ('business_domain' = 'retail',
            'data_layer' = 'dwd',
            'security_level' = 'confidential',
            'lifecycle_stage' = 'hot');

-- 3. 对敏感列打标(列级)
ALTER TABLE prod.retail.dwd_order_detail
  ALTER COLUMN customer_phone
  SET TAGS ('security_level' = 'secret');

ALTER TABLE prod.retail.dwd_order_detail
  ALTER COLUMN order_amount
  SET TAGS ('security_level' = 'confidential');

打标之后,标签的价值才真正体现:它可以被策略直接引用。例如,用列级security_level = 'secret'驱动动态脱敏,用表级lifecycle_stage = 'archive'驱动归档任务,用business_domain驱动数据目录的检索与推荐。下面这段策略示意展示了标签如何与访问控制联动。

-- 基于标签的列级脱敏策略(示意)
CREATE OR REPLACE FUNCTION prod.security.mask_secret(val STRING)
RETURN CASE
  WHEN is_account_group_member('pii_reader') THEN val
  ELSE '***MASKED***'
END;

ALTER TABLE prod.retail.dwd_order_detail
  ALTER COLUMN customer_phone
  SET MASK prod.security.mask_secret;

需要强调的是,标签本身不会自动生效,必须由策略、任务或检索逻辑去消费它。因此设计标签体系时,要同步想清楚“谁来消费这个标签”。如果某个标签没有任何下游消费者,它大概率会在三个月内变成死标签。

四、标签体系的整体结构

下图展示了四个维度如何从受控词表出发,落到Catalog、Schema、Table、Column四层对象上,并最终被安全策略、生命周期任务和数据检索三类消费者使用。图中同时标出了表级与列级标签的差异,以及安全等级取最高敏感级别的合并规则。

Unity Catalog 标签体系:四维度 × 四层对象 × 三类消费者 受控词表(Tag Keys) business_domain retail / supply_chain finance / marketing data_layer ods / dwd / dws ads / feature security_level public / internal confidential / secret lifecycle_stage hot / warm / cold archive / to_delete Unity Catalog 对象层级 Catalog 业务域 + 安全等级(默认继承) Schema 数据域 + 生命周期(默认继承) Table / View 表级:四维度全打 安全等级 = 列级最高值 Column 列级:security_level + 业务口径属性 属性/注释:负责人、SLA、口径说明 标签消费者 安全策略 列级脱敏 / 行级过滤 依据 security_level 生命周期任务 归档 / 降冷 / 清理 依据 lifecycle_stage 数据检索与推荐 按业务域/数据域查找 资产盘点与血缘聚合 成本与容量分析 按生命周期统计存储分布 继承规则:Catalog/Schema 标签向下继承,Table 可覆盖;安全等级取列级最高敏感值;生命周期随状态流转更新

五、落地时的三个关键判断

第一,标签粒度要克制。不是所有字段都值得打标,优先覆盖主键、外键、金额、手机号、身份证号、地址等敏感或高价值字段。第二,继承与覆盖要明确。Catalog和Schema上的标签应作为默认值向下继承,Table可以覆盖,但覆盖必须有记录,否则审计时无法追溯。第三,标签要有生命周期。当表被归档或删除时,标签应同步更新lifecycle_stage,避免出现“已删除的表还挂着hot标签”的脏数据。

安全等级标签一旦用于策略,修改时必须评估影响面。把某列从internal改为secret会立即触发脱敏,可能导致下游报表出现大量MASKED值。建议先在测试Catalog验证策略效果,再推广到生产。

最后给出一个可执行的检查清单,用于验收标签体系是否真正落地:受控词表是否已创建且无自由填写入口;核心表是否四维度齐全;列级安全标签是否覆盖所有敏感字段;是否存在无消费者的死标签;标签变更是否有审计记录;生命周期标签是否与存储层实际状态一致。这六项全部通过,标签体系才算从“设计”走到了“可用”。