4. 元数据分类与标签体系设计
在Unity Catalog中,元数据治理的起点不是“建多少标签”,而是先回答一个更基础的问题:我们究竟要用标签解决哪些问题。标签体系如果只停留在“给表打几个词”的层面,很快就会退化成无人维护的装饰。真正可用的标签体系,必须能同时支撑四类诉求:业务人员按业务域找数据、数据工程师按数据域做分层建模、安全团队按安全等级做访问控制、运维团队按生命周期做成本与归档管理。因此,本节围绕业务域、数据域、安全等级、生命周期四个核心维度展开,并说明如何在Unity Catalog中把标签与属性真正落地。
一、四个标签维度的定位与取值设计
四个维度不是并列的“分类词”,而是各自承担不同治理职责的坐标系。业务域回答“这份数据服务于谁”,数据域回答“这份数据在数仓中处于什么加工层级”,安全等级回答“谁能看、能看多少”,生命周期回答“这份数据该留多久、放在哪一层存储”。
| 维度 | 治理职责 | 典型取值示例 | 是否可多值 |
|---|---|---|---|
| 业务域 | 业务归属与查找入口 | 零售、供应链、金融、营销、客服 | 通常单值,允许主+辅 |
| 数据域 | 数仓分层与加工阶段 | ODS、DWD、DWS、ADS、Feature | 单值 |
| 安全等级 | 访问控制与脱敏策略 | 公开、内部、机密、绝密 | 单值,取最高敏感级别 |
| 生命周期 | 保留、归档、成本管理 | 热、温、冷、归档、待删除 | 单值,随状态流转 |
取值设计要遵循两个原则。第一,枚举封闭:每个维度的取值必须是一份受控词表,不能由用户自由填写,否则“零售”“零售业务”“Retail”会同时出现,标签就失去聚合能力。第二,语义唯一:同一份数据在同一维度上只能有一个权威取值,避免“既是机密又是内部”这类冲突。安全等级尤其如此,应取所有字段中的最高敏感级别作为表级等级。
二、标签与属性的分工
在Unity Catalog中,标签(Tag)和属性(Property/Comment)是两种不同的元数据载体,很多团队会混用。标签是可检索、可策略引用、可跨对象聚合的键值对,适合承载分类维度;属性更多是描述性、说明性的文本,适合承载负责人、SLA、业务口径说明等不适合做枚举的内容。一个实用的分工是:能用受控词表表达的,做成标签;需要自由文本或长描述的,做成属性或注释。
三、在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四层对象上,并最终被安全策略、生命周期任务和数据检索三类消费者使用。图中同时标出了表级与列级标签的差异,以及安全等级取最高敏感级别的合并规则。
五、落地时的三个关键判断
第一,标签粒度要克制。不是所有字段都值得打标,优先覆盖主键、外键、金额、手机号、身份证号、地址等敏感或高价值字段。第二,继承与覆盖要明确。Catalog和Schema上的标签应作为默认值向下继承,Table可以覆盖,但覆盖必须有记录,否则审计时无法追溯。第三,标签要有生命周期。当表被归档或删除时,标签应同步更新lifecycle_stage,避免出现“已删除的表还挂着hot标签”的脏数据。
最后给出一个可执行的检查清单,用于验收标签体系是否真正落地:受控词表是否已创建且无自由填写入口;核心表是否四维度齐全;列级安全标签是否覆盖所有敏感字段;是否存在无消费者的死标签;标签变更是否有审计记录;生命周期标签是否与存储层实际状态一致。这六项全部通过,标签体系才算从“设计”走到了“可用”。