4、维度定义统一:公共维度模型设计、维度映射表与转换规则、维度一致性检查机制
好,咱们进入第四章节。前面几章聊了指标口径冲突的根因和分类,很多同学听完可能会想:「道理我都懂,但具体怎么落地?」
这一章,我就跟你聊聊我这些年最核心的实战经验——维度定义统一。
说白了,指标口径冲突里有一大半,根源都在维度上。同一个「用户」,A 部门定义成「注册手机号」,B 部门定义成「设备 ID」,C 部门定义成「Cookie」。你说这指标能对齐吗?
所以,咱们得从根上把维度管起来。
4.1 公共维度模型设计
我个人习惯,先建一个公共维度模型。这不是什么高大上的理论,就是一张表、一套标准。
我在项目中遇到过最典型的场景:销售看「区域」维度,用的是「省+市+区县」三级;市场部看「区域」,用的是「大区+省+城市」。两边数据一碰,永远对不上。
怎么办?建一个公共的「区域维度表」。
公共维度模型的核心原则:
- 唯一性:每个维度成员有且只有一个编码
- 稳定性:编码一旦分配,永不修改(只做失效标记)
- 可追溯:记录每个维度成员的来源、生效时间、变更历史
举个例子,我们当时设计的公共维度模型结构:
-- 公共维度模型示例:区域维度表
CREATE TABLE dim_region (
region_id VARCHAR(32) PRIMARY KEY, -- 公共编码
region_name VARCHAR(128) NOT NULL, -- 标准名称
region_level TINYINT NOT NULL, -- 层级:1-省 2-市 3-区县
parent_region_id VARCHAR(32), -- 父级编码
source_system VARCHAR(64), -- 来源系统
effective_date DATE NOT NULL, -- 生效日期
expire_date DATE, -- 失效日期
is_active TINYINT DEFAULT 1 -- 是否启用
);
嗯,这里要注意:编码规则一定要统一。我见过最坑的,就是不同系统用不同的编码规则,最后映射表写了一千多行,维护成本极高。
我建议编码规则用「业务域缩写 + 层级 + 序号」,比如 REG_01_001 表示「区域-省-北京」。
4.2 维度映射表与转换规则
公共维度模型建好了,但现实是——你不可能让所有业务系统都改。对吧?
所以,我们需要维度映射表。
你想想看,A 系统叫「province_name」,B 系统叫「region_prov」,C 系统叫「省」。这些都得映射到我们的公共维度编码上。
我的经验:映射表不要只做「一对一」映射。很多场景是「多对一」甚至「多对多」。比如「华东大区」可能对应多个省。这时候,映射表要支持「聚合映射」。
映射表的结构,我一般这样设计:
-- 维度映射表示例
CREATE TABLE dim_mapping_region (
mapping_id BIGINT AUTO_INCREMENT,
source_system VARCHAR(64) NOT NULL, -- 来源系统
source_code VARCHAR(128) NOT NULL, -- 来源编码
source_name VARCHAR(256), -- 来源名称
target_region_id VARCHAR(32) NOT NULL, -- 公共编码
mapping_type VARCHAR(16) DEFAULT '1:1', -- 映射类型:1:1, N:1, 1:N
effective_date DATE NOT NULL,
expire_date DATE,
PRIMARY KEY (mapping_id),
UNIQUE KEY uk_source (source_system, source_code)
);
转换规则呢?我把它分成三类:
| 规则类型 | 说明 | 示例 |
|---|---|---|
| 直接映射 | 源值与目标值一一对应 | 源「北京」→ 公共编码 REG_01_001 |
| 聚合映射 | 多个源值映射到一个目标值 | 源「华东」「华东大区」→ 公共编码 REG_GRP_01 |
| 拆分映射 | 一个源值拆成多个目标值 | 源「京津冀」→ 公共编码 REG_01_001, REG_01_002, REG_01_003 |
避坑指南:我曾经在做一个电商项目时,发现「上海」在订单系统里叫「上海市」,在物流系统里叫「上海」,在财务系统里叫「021」。映射表写了三行,但后来发现「上海市」和「上海」在某个时间点被当成两个不同的维度成员统计了。原因是什么?映射表的生效时间没对齐。
所以,映射表一定要带时间戳,并且要做「时间切片」校验。
4.3 维度一致性检查机制
模型建了,映射表也配了,是不是就万事大吉了?
不是。我见过太多项目,上线第一天跑得好好的,第二天数据就乱了。为什么?因为源系统的维度变了,但映射表没更新。
所以,我们需要一套维度一致性检查机制。
我个人习惯,把它做成一个自动化任务,每天凌晨跑一次。检查什么?
- 完整性检查:源系统的维度值,在映射表里有没有对应的公共编码?
- 一致性检查:同一个公共编码,在不同源系统里对应的值是否一致?
- 时效性检查:映射表的生效/失效时间,是否覆盖了数据的时间范围?
- 冗余性检查:映射表里有没有已经废弃但未标记失效的映射?
检查脚本长什么样?我贴一段核心逻辑:
-- 维度一致性检查:发现未映射的维度值
SELECT
source_system,
source_code,
source_name,
COUNT(*) AS record_count
FROM fact_sales f
LEFT JOIN dim_mapping_region m
ON f.source_system = m.source_system
AND f.province = m.source_code
AND CURRENT_DATE BETWEEN m.effective_date AND COALESCE(m.expire_date, '9999-12-31')
WHERE m.target_region_id IS NULL
GROUP BY source_system, source_code, source_name;
嗯,这段 SQL 看起来简单,但实际跑起来效果很好。我建议把它做成一个数据质量看板,每天自动推送异常结果给数据治理团队。
为什么会这样?因为维度不一致往往是「慢性病」,今天漏一个,明天漏一个,等发现的时候,数据已经乱成一锅粥了。
所以,自动化检查 + 及时告警,才是治本之策。
4.4 知识体系总览
说了这么多,咱们用一张图把这一章的核心逻辑串起来:
这张图把咱们这一章的核心逻辑串起来了:公共维度模型是底座,维度映射表是桥梁,一致性检查是保障。三者缺一不可。
好了,这一章就聊到这儿。记住:维度统一是数据治理的「地基」,地基不稳,上面盖的指标大楼迟早要塌。