数仓规范化设计
概述
数仓混乱的根源往往不是技术,而是"没有规矩"。规范化设计把命名、类型、生命周期、权限变成可执行的约定,让任何开发都能读懂别人的表、放心复用别人的数。本文给出可直接套用的规范模板与落地机制。
一、命名规范
1.1 表命名
层级前缀_业务域_业务过程[_粒度/属性] 如 dwd_order_detail、dws_user_daily| 层级 | 前缀 | 示例 |
|---|---|---|
| ODS | ods_ | ods_order |
| DWD | dwd_ | dwd_order_detail |
| DWS | dws_ | dws_user_daily |
| ADS | ads_ | ads_gmv_daily |
| DIM | dim_ | dim_user |
| 临时 | tmp_ | tmp_xxx |
| 维度字典 | dwd_dic_ | dwd_dic_pay_type |
业务域统一:交易(order)、用户(user)、商品(product)、营销(marketing)、风控(risk)。
1.2 字段命名
| 规则 | 示例 |
|---|---|
| 小写下划线 | user_id、order_amount |
| 主键 | 表名 + _id 或 id |
| 外键 | 引用表名 + _id |
| 时间字段 | 语义 + _time,如 create_time |
| 日期字段 | 语义 + _date,如 pay_date |
| 金额字段 | 语义 + _amount,如 pay_amount |
| 数量字段 | 语义 + _count,如 order_count |
| 比率字段 | 语义 + _rate,如 pay_rate |
1.3 分区与文件
| 项 | 规范 |
|---|---|
| 分区字段 | 统一 dt(按天)、hour(按小时) |
| 分区值 | yyyyMMdd |
| 文件格式 | Parquet/ORC + Snappy/ZSTD |
| 压缩 | 统一选择,禁止混用 |
二、类型约定
2.1 字段类型标准
| 语义 | 推荐类型 | 禁止 |
|---|---|---|
| 主键/ID | BIGINT 或 STRING | 用 INT 存大 ID |
| 金额 | DECIMAL(10,2) 起 | FLOAT/DOUBLE(精度丢失) |
| 日期 | DATE / STRING yyyy-MM-dd | 时间戳当日期用 |
| 时间 | TIMESTAMP | 字符串时间 |
| 状态枚举 | STRING + 字典表 | 裸数字状态 |
| 标志位 | STRING Y/N | 0/1 混用 |
2.2 编码与空值约定
| 项 | 约定 |
|---|---|
| 编码 | 统一 UTF-8 |
| 空值 | 业务空用 NULL,数字缺省用 0 需注明 |
| 金额精度 | 统一保留 2 位,计算中间保留 4 位 |
| 单位 | 金额统一元、时长统一秒,字段名体现单位 |
三、生命周期管理
3.1 表生命周期状态
| 状态 | 说明 | 管理动作 |
|---|---|---|
| 开发中 | 未上线 | 仅开发组可写 |
| 已上线 | 生产使用 | 只读 + 授权管理 |
| 已废弃 | 无消费 | 下线归档 |
| 已删除 | 归档期满 | 物理清理 |
3.2 生命周期规则
| 规则 | 说明 |
|---|---|
| 上线准入 | 新表须带:责任人、数据字典、质量规则、消费方 |
| 变更通知 | 结构变更须通知下游并做影响分析 |
| 定期体检 | 月度盘点访问量,识别僵尸表 |
| 删除审批 | 删除表走审批,先归档后删除 |
3.3 数据保留策略
| 层 | 建议保留 |
|---|---|
| ODS 原始 | 30 天~半年(视合规) |
| DWD 明细 | 1 年 |
| DWS 汇总 | 2~3 年 |
| ADS | 按业务要求 |
| DIM 拉链 | 永久 |
四、权限模型
4.1 权限层级
| 层级 | 粒度 | 说明 |
|---|---|---|
| 库级 | 整库 | 开发/只读 |
| 表级 | 单表 | 细粒度控制 |
| 字段级 | 敏感列 | 脱敏、禁止导出 |
| 行级 | 数据范围 | 按业务域过滤 |
4.2 角色设计
| 角色 | 权限 |
|---|---|
| 数据开发 | 读写所在业务域、可写临时表 |
| 数据分析师 | 只读消费层(DWS/ADS) |
| 数据科学家 | 只读 + 指定沙箱 |
| 管理员 | 全库 + 权限管理 |
| 审计 | 只读 + 审计日志 |
4.3 权限落地(Ranger 示例)
| 策略对象 | 规则 |
|---|---|
| 开发组 | dwd_*、dws_* 读写 |
| 分析组 | ads_* 只读 |
| 敏感字段 | 手机号列脱敏,* 号显示 |
| 导出控制 | 大批量导出需审批 |
五、开发规范
5.1 SQL 开发规范
| 项 | 约定 |
|---|---|
禁止 SELECT * | 显式列名,血缘可解析 |
| 分区过滤 | 查询必带分区条件,禁止全表扫 |
| 幂等 | 任务可重跑,Insert Overwrite 而非 Append |
| Join 大小表 | 小表在前,支持 MapJoin |
| 代码评审 | 上线前评审 + 质量规则绑定 |
5.2 调度规范
| 项 | 约定 |
|---|---|
| 依赖声明 | 显式声明上游表依赖 |
| 重试策略 | 失败自动重试 2~3 次 |
| 告警 | 失败/超时必告警 |
| 参数化 | 日期参数化,支持补数 |
六、规范落地机制
6.1 落地三步
1. 文档化:把规范写入数据开发平台的规则中心
2. 工具化:命名/类型规则用检查工具自动校验(CI 卡点)
3. 评审化:新表上线走评审流程,不合规不放行6.2 常见反模式与对策
| 反模式 | 对策 |
|---|---|
| 表名随意(test、temp) | 命名规范 + 工具校验 |
| 金额用 DOUBLE | 类型约束 + 检查工具 |
| SELECT * 满天飞 | 代码评审卡点 |
| 无责任人 | 上线准入必填责任人 |
| 权限一刀切 | 分级角色 + Ranger 细粒度 |
小结
规范化设计的意义不是"多写文档",而是把约定变成工具和流程:命名靠校验、类型靠约束、生命周期靠准入、权限靠平台。规范先立起来,数据质量与协作效率才有根基。