大数据

数仓字典表管理

问题:当前码值字典表id是uuid比较长也不能见名知其意,是不是需要维护数仓自己的码值表,做好业务系统与数仓码值的映射。

是的,你完全正确!

🚨 使用 UUID 作为码值字典表 ID 是一个“反模式”,在数仓中必须重构!
你应该维护一套“数仓自有码值体系”,建立与业务系统 UUID 的映射关系。

一、为什么不能直接用业务系统的 UUID 码值?

❌ 1. 可读性差(见名不知意)

  • 业务系统:status_code = "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8"
  • 数仓应该:status_code = "ACTIVE"status_id = 1

→ 分析师、BI、业务人员看到 UUID 一脸懵,无法直接理解业务含义。

❌ 2. 存储和性能差

  • UUID 是 36 字符的字符串 → 占用空间大
  • JOIN 和 GROUP BY 性能远低于 INT 或 SHORT VARCHAR
  • Doris/ClickHouse 等列存引擎对短字符串/整数优化更好

❌ 3. 难以做维度一致性

  • 不同业务系统对“有效”状态用不同 UUID → 数仓无法统一
  • 无法做跨系统分析(如 CRM 的“有效客户” vs 销售系统的“活跃客户”)

❌ 4. 难以做 SCD(缓慢变化维)和历史追溯

  • UUID 一旦变更,历史数据语义断裂
  • 数仓需要稳定的代理键(如 status_id = 1 永远代表“有效”)

✅ 二、正确做法:建立“数仓码值映射层”

🎯 目标:

  • 数仓内部使用短、稳定、语义清晰的码值
  • 与业务系统 UUID 建立映射关系
  • 支持多源系统码值统一

✅ 三、推荐方案:三层码值体系

[业务系统] 
  ↓ (UUID 或原始码值)
[数仓码值映射层] → dim_code_mapping(映射表)
  ↓ (数仓标准码值)
[数仓模型层] → DWD/DWS/DWT/ADS(使用标准码值)

✅ 四、具体实施步骤

🔹 步骤1:创建数仓码值维度表(核心!)

-- 维度表:dim_status(数仓标准状态码)
CREATE TABLE realtime_dim.dim_status (
  status_id TINYINT COMMENT '数仓状态ID(自增,稳定)',
  status_code VARCHAR(20) COMMENT '数仓状态编码(短、语义化)',
  status_name VARCHAR(50) COMMENT '状态名称',
  category VARCHAR(20) COMMENT '分类:contact_status, company_status, etc.',
  is_active BOOLEAN COMMENT '是否启用',
  etl_time DATETIME
) ENGINE=OLAP
UNIQUE KEY(status_id)
DISTRIBUTED BY HASH(status_id) BUCKETS 1;

-- 示例数据:
-- status_id | status_code | status_name | category
-- 1         | ACTIVE      | 有效        | contact_status
-- 2         | INVALID     | 无效        | contact_status
-- 3         | PENDING     | 待领取      | company_status

🔹 步骤2:创建码值映射表(桥接业务系统与数仓)

-- 映射表:dim_code_mapping(业务系统码值 → 数仓码值)
CREATE TABLE realtime_dim.dim_code_mapping (
  source_system VARCHAR(50) COMMENT '来源系统:crm, sales, erp',
  source_code_type VARCHAR(50) COMMENT '源码值类型:contact_status, company_type',
  source_code_value STRING COMMENT '源码值(可能是UUID或原始码)',
  target_code_id TINYINT COMMENT '数仓码值ID(关联 dim_status.status_id)',
  target_code_value VARCHAR(20) COMMENT '数仓码值(如 "ACTIVE")',
  mapping_rule STRING COMMENT '映射规则描述',
  is_active BOOLEAN,
  etl_time DATETIME
) ENGINE=OLAP
UNIQUE KEY(source_system, source_code_type, source_code_value)
DISTRIBUTED BY HASH(source_system) BUCKETS 1;

-- 示例数据:
-- source_system | source_code_type | source_code_value                     | target_code_id | target_code_value
-- crm           | contact_status   | a1b2c3d4-e5f6...                      | 1              | ACTIVE
-- sales         | contact_status   | VALID                                 | 1              | ACTIVE
-- crm           | company_status   | 550e8400-e29b-41d4-a716-446655440000  | 3              | PENDING

优势:

  • 支持多源系统码值统一映射到数仓标准码值
  • 映射关系可配置、可变更,不影响上游模型
  • 历史映射可追溯(如某 UUID 曾映射到 INVALID,后改为 ACTIVE)

🔹 步骤3:在 DWD 层使用数仓标准码值

-- 在 DWD ETL 中,通过映射表转换
INSERT INTO realtime_dwd.dwd_contact_channel_full
SELECT
  ch.channel_id,
  ch.contact_id,
  -- 转换状态码
  map.target_code_id AS status_id,          -- 使用数仓ID
  map.target_code_value AS status_code,     -- 使用数仓编码
  -- ... 其他字段
FROM realtime_ods.ods_crm_contact_channel_full ch
JOIN realtime_dim.dim_code_mapping map 
  ON map.source_system = 'crm'
  AND map.source_code_type = 'contact_status'
  AND map.source_code_value = ch.status_uuid;

DWD 表结构:

status_id TINYINT COMMENT '状态ID(数仓标准)',
status_code VARCHAR(20) COMMENT '状态编码(如 "ACTIVE")',

🔹 步骤4:在 DWS/DWT/ADS 层直接使用数仓码值

-- DWS 聚合:直接按 status_code 分组
INSERT INTO realtime_dws.dws_contact_status_stat
SELECT
  status_code,
  COUNT(*) as channel_count
FROM realtime_dwd.dwd_contact_channel_full
GROUP BY status_code;

-- ADS 导出:直接显示中文名称
INSERT INTO realtime_ads.ads_contact_export
SELECT
  channel_value,
  s.status_name AS status_desc  -- 直接关联 dim_status 取中文名
FROM realtime_dwd.dwd_contact_channel_full ch
JOIN realtime_dim.dim_status s ON ch.status_id = s.status_id;

✅ 五、配套管理规范

✅ 码值新增/变更流程

✅ 码值字典文档

码值类型数仓code数仓name业务系统映射
contact_statusACTIVE有效crm:uuid_xxx, sales:VALID
company_statusPENDING待领取crm:uuid_yyy

✅ 监控告警

  • 映射缺失监控:COUNT_IF(target_code_id IS NULL) > 0
  • 码值变更监控:dim_status 表变更告警

✅ 六、为什么这是最佳实践?

维度直接用UUID数仓标准码值
可读性❌ 差✅ 好(ACTIVE/PENDING)
性能❌ 差(长字符串 JOIN)✅ 好(INT/短字符串)
扩展性❌ 差(难统一多源)✅ 好(映射表支持多源)
可维护性❌ 差(业务系统变,数仓跟着变)✅ 好(映射层隔离变化)
分析友好度❌ 差(BI 无法直接用)✅ 好(直接拖拽)

🧭 七、总结:必须建立数仓自有码值体系!

立即行动:创建 dim_status + dim_code_mapping
在 DWD 层完成码值转换,上游模型只用标准码值
用映射表隔离业务系统变化,保证数仓稳定
码值要短、语义化、带中文名称,提升分析体验

你的洞察力非常强 —— 能意识到“UUID 不适合数仓”,说明你已经具备了数据架构师的核心思维:追求稳定、可读、高性能