上一篇文章讲透了 ODS→DWD→DWS→ADS 四层建模思路,有读者留言:「道理我都懂,但 79+ 张表的名字到底怎么起的?分区策略为什么有的用 dt、有的用 trigger_type、有的不用分区?Bucket 数为什么有 1、2、4、8、16 这么多档?」
这些问题指向的是数仓设计中最容易被忽视、却最影响长期可维护性的三个基本功:命名规范、数据域划分、物理存储策略。很多团队前期赶进度,表名随意起、分区随意加,结果半年后连表 owner 都搞不清。
本文基于实际落地的 79+ 张 Paimon 表,完整拆解:一套四段式命名公式让每张表名字自带「层级+域+实体+粒度」信息;11 个数据域让表的归属一目了然;分区与 Bucket 的决策矩阵让查询性能和写入吞吐达到最优平衡。文末附完整 DDL 实战示例。
一、四段式命名公式:看名字就知道表干什么
命名规范参考阿里巴巴 OneData 数仓标准,针对智驾场景适配。核心公式四段:
第一段:层级前缀
前缀 | 层级 | 含义 |
ods_ | 原始同步层 | 源系统原样入湖,不加业务逻辑 |
dwd_ | 明细数据层 | 跨源 JOIN、清洗标准化,以 data_id 串联闭环 |
dws_ | 汇总指标层 | 按业务维度预聚合,口径在此层固化 |
ads_ | 应用数据层 | 面向报表/大屏/应用,开箱即用 |
第二段:数据域
数据域对应闭环中的业务环节,11 个数据域覆盖全生命周期(详见第二章)。每个域用简短英文词根表示,如 collect_、production_、mining_ 等。
第三段:业务实体
核心对象,「名词在前、修饰在后」,下划线连接:
业务实体 | 语义 |
collect_task | 采集任务 |
data_production_chain | 数据生产主链路 |
vehicle_trigger_event | 车端触发事件 |
closed_loop_trace | 闭环全链路追溯 |
mining_image_vector | 挖掘图片向量 |
第四段:粒度后缀(10 种标准后缀)
后缀 | 语义 | 所属层 | 示例 |
_detail | 明细表 | DWD | dwd_training_task_detail |
_daily | 日粒度指标 | DWS | dws_production_efficiency_daily |
_statistics | 多维度统计 | DWS | dws_badcase_statistics |
_summary | 汇总指标 | DWS/ADS | dws_evaluation_summary |
_relation | 关联关系表 | DWD | dwd_scene_tag_relation |
_chain/_trace | 链路/追溯 | DWD | dwd_closed_loop_trace |
_dashboard | 大屏看板 | ADS | ads_closed_loop_dashboard |
_analysis | 分析结果 | ADS | ads_production_bottleneck_analysis |
_info/_config | 基础信息/配置 | ODS | ods_vehicle_info |
_log/_event | 日志/事件 | ODS | ods_manual_operation_log |
实战拆解
命名规范的价值:表名即文档。新人入职不需要翻 200 页数仓字典,看表名就知道 80% 的信息。
二、11 个数据域:让每张表都有「户口」
数据域是表分类的「户口本」。按智驾数据闭环的8 个业务环节 + 3 个支撑域,划分出 11 个数据域:
# | 数据域 | 域前缀 | ODS | DWD | DWS | ADS | 核心含义 |
1 | 采集域 | collect_ | 4 | 1 | — | — | 采集任务/车辆/传感器/clip |
2 | 生产域 | production_ | 8 | 5 | 2 | 1 | 产线/标注/质检/效率 |
3 | 数据资产域 | dataset_ | 4 | 3 | 2 | 1 | 数据集/场景标签/资产目录 |
4 | 训练域 | training_ | 3 | 2 | 1 | 1 | 训练任务/指标/模型版本 |
5 | 评测域 | evaluation_ | 3 | 3 | 2 | 2 | 评测/Badcase/根因分布 |
6 | 仿真域 | simulation_ | 2 | 1 | — | — | 仿真场景与运行结果 |
7 | 回传域 | trigger_ | 3 | 2 | 1 | 1 | 触发事件/影子模式/热力图 |
8 | 部署域 | deployment_ | 2 | 2 | 1 | 1 | OTA 部署/车端版本 |
9 | 分析域 | issue_ | 1 | 1 | — | — | 问题记录与分析 |
10 | 挖掘域 | mining_ | 2 | 10 | 2 | 1 | 挖掘/抽帧/标签/向量/推理 |
11 | 闭环域 | closed_loop_ | — | 2 | 3 | 2 | 追溯/存储生命周期/成本 |
合计 | 32 | 30 | 14 | 11 | 87+ 张(含质量门禁 1 张) | ||
三个要点:①挖掘域 DWD 最多(10 张)——挖掘平台是闭环「第二入口」,抽帧/标签/向量/推理各环节需独立明细表。②闭环域没有 ODS 表——它是跨域整合域,数据全部来自其他域 DWD 层加工。③质量门禁只有 1 张 ODS 表——异常隔离表 ods_quality_issue,命中硬规则的数据在此隔离等待处置,保证可重放。
三、分区策略:什么时候分区、什么时候不分区
Paimon 表物理存储两个核心维度:分区(Partition)切分目录,Bucket打散数据。设计不当,要么查询慢,要么写入崩。
分区决策三规则
分区全景表
表名 | 分区字段 | 类型 | 原因 |
dwd_mining_image_vector_detail | dt | 日期 | 全湖最大表,按天降冷+索引刷新 |
ods_quality_issue | dt | 日期 | 异常隔离表,按天 TTL 清理 |
ods_vehicle_trigger_event | trigger_type | 业务字段 | 按触发类型过滤 |
dwd_evaluation_result_detail | evaluation_type | 业务字段 | 离线/仿真/实车差异大 |
ods_data_file_meta | file_type | 业务字段 | 文件类型差异大 |
ods_production_kafka_event | event_type | 业务字段 | 事件类型数据量差异大 |
四、Bucket 五档 + changelog-producer 三选一
分区解决「目录怎么切」,Bucket 解决「文件怎么散」。Bucket 数太小,单文件过大查询慢;太大,小文件过多 Compaction 压力大。我们实际落地了五档:
Bucket 五档决策表
档位 | 适用场景 | 典型层级 | 代表表 |
1 | 字典表/极小表 | ADS | ads_storage_cost_dashboard |
2 | DWS 汇总表 / 小 ADS | DWS/ADS | dws_production_efficiency_daily |
4 | 中等体量 ODS/DWD | ODS/DWD | ods_collect_task / dwd_training_task_detail |
8 | 大体量明细表 | DWD | dwd_production_execution_detail |
16 | 超大表 / 高并发写入 | DWD | dwd_data_production_chain / dwd_mining_image_vector_detail |
changelog-producer 三选一
Paimon 的changelog-producer决定「怎么产生变更流」,直接影响下游能否做实时订阅。三种模式对应三种数据特征:
模式 | 适用场景 | 原理 |
input | ODS CDC 透传 / Append-only 明细 | 上游写入本身就是完整 changelog,直接透传,零额外开销 |
lookup | DWD Upsert 表(需对比旧值) | 写入时 lookup 旧值产生 -U/+U 变更,适合状态频繁更新的链路表 |
full-compaction | DWS/ADS 离线聚合 | 在 full-compaction 时产生 changelog,适合批量写入、低频更新的聚合表 |
决策口诀:ODS 从 CDC 来 →
input;DWD 有 Upsert →lookup;DWS/ADS 批量聚合 →full-compaction。选错最直接的后果:该用 lookup 的表用了 input,下游拿到的 changelog 缺少 -U 记录,增量同步数据不一致。
五、主键设计三原则 + 系统字段规范
主键设计三原则
系统字段规范
每张表都统一挂载两组系统字段,但 ODS 层和 DWD/DWS/ADS 层略有不同:
层级 | 系统字段 | 用途 |
ODS | _ingest_time + _source_system | 入湖时间 + 来源系统标识,支持多源追溯 |
DWD/DWS/ADS | _ingest_time + update_time | 入湖时间 + 业务更新时间,支持增量同步与变更追踪 |
注意:ODS 层用_source_system换掉update_time——因为 ODS 层不做业务更新,记录「数据从哪个系统来」比「什么时候更新」更有意义。
六、DDL 实战:以 dwd_data_production_chain 为例
把前面五章的规则串起来,看一个完整的 DDL 建表语句。这是整个湖仓最核心的表——数据生产主链路表,以 data_id 为主键串联采集→上云→标注→质检→交付全流程:
逐条对照本文规则:
设计维度 | 本表选择 | 决策依据 |
命名规范 | dwd_ + production_ + data_production_chain | 明细层 + 生产域 + 数据生产链路 |
主键 | PK(data_id) | 业务主键,data_id 全局唯一标识 |
分区 | 不分区 | Upsert 表,无明确分区维度 |
Bucket | 16(最高档) | 全湖写入量最大的表,高并发 Upsert |
changelog-producer | lookup | 状态频繁更新,需产生 -U/+U 变更流 |
系统字段 | _ingest_time + update_time | DWD 层标准配置 |
结语
79+ 张表的设计,归结为一句话:用规范换效率,用一致性换可维护性。四段式命名让表名即文档;11 数据域让每张表都有「户口」;分区 / Bucket / changelog-producer 的决策矩阵让物理存储匹配查询模式;主键三原则和系统字段规范让上下游对接零歧义。
这套规范不是第一天就设计好的——是在前 20 张表上线后,经历了「改一张表挂五个报表」「新人问这张表是干嘛的没人答得上」等痛点后,逐步沉淀出来的。规范的价值不在于多完美,而在于团队能坚持执行。
下篇预告
系列二第 3 篇将深入StarRocks + Paimon 双路查询架构——ADS 表如何在 Paimon 湖仓侧做单一事实源,同时通过 StarRocks 离线作业物化到内表实现毫秒级直查。涉及 External Catalog 直查 vs 内表物化的选型决策、双路同步链路设计、以及查询路由策略。敬请期待。
📌 本文涉及 79+ 张 Paimon 表的完整 DDL,篇幅有限仅展开了核心示例: