ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

数据中台建设实战:四层架构、分层建模与指标口径落地

数据中台建设实战:四层架构、分层建模与指标口径落地

简介:《数据中台实战:手把手教你搭建数据中台》电子书,面向寻求数据化转型的企业高层、产品经理、运营设计与开发人员,以及对数据领域感兴趣的学生和从业者,回应数据中台“是什么、为何要建、究竟怎么建”三个核心疑问。压缩包内为1个PDF文件,约11.3MB,即该书完整电子版,便于离线阅读与按章节检索,已有402人学习下载。全书以作者董超华在大型企业从0到1搭建中台的经历为底本,沿数据采集、数据存储与计算、数据打通、数据应用四条主线展开:埋点采集用户行为与业务数据,ODS到DWD/DWS再到ADS的分层建模与指标管理体系,标签平台与用户画像消除数据孤岛,以及用户、商品、流量、交易四类分析和自助分析平台、自动化营销平台。各章配有实战案例,并反复提示先判断自身业务密度与复杂度是否适配中台,避免盲目上马导致水土不服,可作为中台产品经理与转型团队的落地参考。

1. 从零搭数据中台:先判断该不该建,再谈怎么建

有个团队找我,说要做数据中台,技术方案已经写了两版,问我选哪套组件。我没看方案,先问了三个问题:你们现在有几条产品线,通用模块的复用度有多高,指标口径出问题谁签字。三个问题答上来一个。这不是选型问题,是需求还没立住。数据中台实战里最常见的翻车,不是大数据组件堆不出来,而是业务密度不够硬上,最后采集、存储、打通、应用四段链路只有采集在跑,后面三段全是空壳。这套方案适合的是产品线在三条以上、用户与交易数据散落在多个系统、并且已经有人愿意为口径背书的团队;只有一条核心产品线的业务,先把埋点和报表做扎实,比建中台划算得多。

2. 总体架构与组织:四层链路和十个角色的职责边界

动手之前,架构和组织要一起定,因为中台从来不是纯技术项目。这一章把「该不该建」的判断标准、四层链路的职责划分、以及人员怎么排这三件事说清楚,后面三章才有落脚点。

2.1 先判断业务密度:三条产品线是分水岭

判断标准很朴素:产品线数量、模块复用度、数据分散程度。产品线只有一条,所有数据天然在一个库里,做数据仓库就够了,中台的组织成本反而拖慢迭代。产品线到三条以上,账号、支付、营销这类模块被重复开发,用户在不同产品之间来回跳,数据开始出现「同一个人三个 ID」的情况,这时候中台才有存在意义。

业务中台和数据中台的关系要理清:业务中台把通用能力收拢,让一切业务数据化;数据中台把各产品线的数据回收、打通、再以接口和产品形态还回去,让一切数据业务化。公司如果已经有业务中台,数据中台的采集工作量会小很多,因为通用业务数据已经集中存放,不用逐条产品线做调研对接;没有业务中台也能建,只是采集端要多写几套同步任务,沟通成本翻倍。我一般会建议先把业务中台的用户中心和交易中心落地,再启动数据中台,顺序反了会很别扭。

前期投入是实打实的:采集链路、分层建模、指标规范、标签平台,每一项都要人。但产品线继续扩张时,新建产品线只需接中台,不再重复造轮子。这笔账要按两年以上的周期算,按季度算一定亏。

2.2 四层总体架构:采集、计算、服务、应用各管什么

从下往上四层,职责不重叠是设计底线。

层级核心职责典型产出常见误用
数据采集层把业务库、日志、第三方数据抽进中台埋点日志、增量同步任务把清洗逻辑塞进采集,导致源头不可回溯
数据计算层分层建模、指标计算、口径统一ODS/DWD/DWS/ADS 各层表跳过 DWD 直接从 ODS 出报表
数据服务层把计算结果封装成接口对外提供指标查询接口、标签查询接口每个看板直连底表,接口层形同虚设
数据应用层面向内部、用户、商家的数据产品人货场看板、自助分析、推荐应用层自己算指标,口径又分裂一次

采集层只做搬运和落地,原始数据进 ODS 后不再改动,这是后面所有排查的后悔药。计算层是中台的心脏,分层不是为了好看,是为了让「明细可追溯、汇总可复用」。服务层常被忽略,很多团队做完看板就让业务直连 Hive 表,结果一个字段改名,十几个看板同时挂掉。应用层则要克制,看板上出现的每个数字都应该来自服务层接口,而不是应用自己写 SQL 再算一遍。

数据在这四层里是单向流动的:业务库和日志 → ODS 贴源 → DWD 清洗 → DWS 汇总 → ADS 应用 → 接口 → 看板。任何反向依赖,比如 DWD 去读 ADS 的结果,都属于架构事故,早晚出问题。

2.3 组织与角色:十个角色怎么排班

中台是「一把手工程」这句话不是口号。业务中台要收拢各产品线的核心业务,数据中台要收拢所有数据,跨部门协调量极大,没有高层直接主管,推动不动。典型结构是:高层之下设中台负责人,统一管理业务中台和数据中台两个团队,两边产生分歧时由中台负责人裁决,比如业务中台改了订单状态机,数据中台的交易指标口径必须同步。

数据中台内部通常要凑齐十种角色:中台负责人、数据产品经理、数据分析师、数据开发工程师、算法工程师、ETL 工程师、测试工程师、运维工程师、业务方接口人、项目经理。小团队可以一人多岗,但有三件事必须有人明确负责:指标口径的最终解释权归数据产品经理;调度任务的稳定性归数据开发和运维;业务方要有一个固定接口人,否则需求会从十个方向涌进来。

提示:角色表要落成文档并公示,尤其是「谁对指标口径负责」这一条。没有这一条,后面所有口径争议都会变成会议。

3. 数据采集与分层建模:埋点参数、指标口径与 ODS 到 ADS 的建表方式

采集和建模是整套方案里最枯燥、也最不能省的两段。这一章给出可直接改用的表结构、指标规范和分层 SQL,重点不在语法,而在每个字段为什么这么设计。

3.1 两条采集链路:行为埋点与业务数据同步

行为数据走埋点。客户端 SDK 按事件模型上报,一个事件包含事件名、页面标识、元素标识、业务属性、时间戳五类信息,批量打包后落到日志文件,再按天抽进 ODS。业务数据走数据库同步,订单、支付、商品这类表用增量字段或日志订阅做准实时同步,维表用全量覆盖加每日快照。两条链路的落点是同一层 ODS,但分区和保留策略分开管。

-- ODS 层:贴源存储客户端上报的埋点日志,保留原始字段不做任何清洗 CREATE TABLE ods_event_log ( user_id STRING COMMENT '登录用户ID,未登录时为空', device_id STRING COMMENT '设备ID,未登录场景下作为临时主键', event_name STRING COMMENT '事件名,如 page_view / item_click / order_submit', page_id STRING COMMENT '页面标识,与前端路由表对齐', properties STRING COMMENT '事件属性JSON,如 {"item_id":"1001","position":3}', report_ts BIGINT COMMENT '客户端上报时间戳,毫秒', dt STRING COMMENT '分区字段,格式 yyyy-MM-dd' ) PARTITIONED BY (dt STRING) STORED AS ORC;

这段建表有三个设计点。第一,user_id和device_id并存,未登录用户的行为也必须留下,否则新客转化漏斗从第一步就断了。第二,properties用 JSON 存扩展属性,埋点需求天天变,每加一个属性就改表结构不现实,代价是查询时要解析,所以只放非核心属性,item_id、amount这类高频字段建议单独提列。第三,分区按天,配合保留策略,原始日志一般留 90 天足够回溯,长期留存的是 DWD 层。

同步任务要盯三个参数:增量字段(必须是单调递增且业务上可靠的,比如自增 ID 或更新时间)、同步频率(交易类表 5 到 15 分钟,维表每天一次)、失败重试次数(建议 3 次,超过就告警,不要无限重试把上游库拖垮)。

3.2 指标管理体系:一个指标必须写清五件事

指标打架的根源是定义不完整。一个合格指标条目要写清:业务口径(业务方怎么理解这个数)、技术口径(对应哪张表哪个字段做什么过滤)、计算周期(日/周/月,是否含当天)、可用维度组合(能按渠道拆还是只能按品类拆)、责任人(口径变更时谁确认)。缺任何一项,三个月后一定有人问「这个 GMV 含不含退款」。

命名也要统一,通常用「域_业务过程_度量_周期」的结构,比如trade_order_pay_amt_1d表示交易域下单支付的金额日粒度。命名规范的价值在于,看到表名就知道能不能用,不用点进去看注释。指标字典要落库管理,新增指标走评审,变更指标走版本,旧版本保留至少一个周期再下线。

-- DWD 层:清洗后的下单明细事实表,统一字段命名并剔除测试账号 INSERT OVERWRITE TABLE dwd_trade_order_di PARTITION (dt = '${bizdate}') SELECT o.order_id, o.user_id, o.item_id, o.pay_amount, -- 实付金额,单位元,已扣除优惠 o.order_status, o.create_time, o.pay_time FROM ods_order o LEFT JOIN dim_user u ON o.user_id = u.user_id WHERE o.dt = '${bizdate}' AND COALESCE(u.is_test, 0) = 0 -- 过滤内部测试账号,避免污染指标 AND o.order_status <> 'invalid'; -- 无效单不进事实表

DWD 层的职责是清洗和标准化:字段重命名、金额单位统一、时区统一、测试数据剔除、无效状态过滤。这一段做不干净,后面所有汇总都是脏的,而脏数据最难查,因为表面数字看着合理。

3.3 分层建模:ODS 到 ADS 各层建什么、留多久

ODS 贴源,字段和上游保持一致,只加分区和同步时间,保留 90 天。DIM 存维度,用户、商品、渠道、门店,缓慢变化维用拉链表保留历史,否则三个月前的订单按今天的品类归属统计,报表会莫名其妙变化。DWD 存明细事实,按主题域划分,交易、流量、营销各一套,保留一年以上。DWS 按「主题 + 粒度」汇总,比如用户日粒度交易汇总、商品日粒度销售汇总,这一层是复用率最高的,看板和标签平台都从这里取数。ADS 面向具体应用,一个看板一组表,允许冗余,追求查询快。

-- DWS 层:用户日粒度交易汇总,同时供用户分析看板和标签平台使用 INSERT OVERWRITE TABLE dws_user_trade_1d PARTITION (dt = '${bizdate}') SELECT user_id, COUNT(DISTINCT order_id) AS order_cnt, -- 当日下单笔数,已去重 SUM(pay_amount) AS pay_amt, -- 当日实付金额 MAX(pay_time) AS last_pay_time -- 最近支付时间,用于活跃判断 FROM dwd_trade_order_di WHERE dt = '${bizdate}' AND pay_time IS NOT NULL -- 只统计已支付,未支付不进汇总 GROUP BY user_id;

分层的实际收益在排查时体现。指标异常,先看 ADS 是否符合预期,再看 DWS 汇总是否漏了维度,再看 DWD 明细是否有异常记录,最后回到 ODS 和原始日志。这条链路清晰,半小时能定位;不分层,所有逻辑揉在一张宽表里,那就是个黑匣子,只能靠猜。

生命周期策略要提前定:ODS 90 天,DWD 永久或 3 年,DWS 2 年,ADS 按业务需要。存储成本主要压在 ODS 和 DWD,压缩格式选 ORC 或 Parquet,分区字段放最后,避免小文件。

4. 数据打通与数据应用:宽表、标签平台到人货场看板的落地链路

数据打通解决的是「同一个用户在三套系统里是三个人」的问题,数据应用解决的是「打通之后给谁用、怎么用」。这两段接不上,中台就只是个大号数据仓库。

4.1 宽表设计:行为数据与业务数据怎么对齐

打通的第一步是统一 ID。以user_id为主键,把设备 ID、手机号、第三方 OpenID 映射到同一张 ID-Mapping 表,映射关系按「强关联优先」维护:登录态下的设备与账号绑定置信度最高,同一手机号次之,同设备多账号要谨慎,可能是家庭共用设备。

宽表不是越宽越好。我一般按「一个主题一张宽表」来做,用户宽表放属性、交易汇总、行为汇总三类字段,字段数量控制在 60 个以内,超过就拆。宽表每天一个快照分区,不做全量更新,查询时取最新分区,好处是任意一天的历史状态都能复现。

-- 用户宽表:属性、交易、行为三路数据按 user_id 对齐,每天一个快照 INSERT OVERWRITE TABLE ads_user_wide_1d PARTITION (dt = '${bizdate}') SELECT u.user_id, u.register_channel, -- 注册渠道,来自用户维表 u.register_dt, COALESCE(t.order_cnt_30d, 0) AS order_cnt_30d, COALESCE(t.pay_amt_30d, 0) AS pay_amt_30d, COALESCE(b.active_days_30d, 0) AS active_days_30d, b.last_active_dt FROM dim_user u LEFT JOIN dws_user_trade_30d t ON u.user_id = t.user_id LEFT JOIN dws_user_behavior_30d b ON u.user_id = b.user_id WHERE u.dt = '${bizdate}';

这里用 LEFT JOIN 而不是 INNER JOIN,是为了保留「注册了但从没下单」的用户,这类人群在召回场景里价值很高。COALESCE把空值补零,避免下游做聚合时出现 NULL 传播。30 天窗口是经验值,太短区分不出用户层级,太长会把沉睡用户算成活跃。

打通还要处理产品线之间的数据。同一个用户在 A 产品下单、在 B 产品浏览,只有把两条产品线的行为日志归到同一个user_id下,才能看出「浏览 A 买 B」这种跨线行为,这类结论往往是业务最想要的。

4.2 标签体系:从定义、生成到人群圈选

标签平台是用户画像和推荐系统的基础。标签分三类:事实类(累计下单金额、注册天数)、规则类(近 30 天活跃、高价值用户)、模型类(流失概率、偏好品类)。事实类每天跑,规则类按需跑,模型类周期跑,更新频率要写进标签定义表,不能让业务方猜。

-- 标签定义表:每个标签的口径、更新周期、责任人必须固化在表里 CREATE TABLE dim_tag_definition ( tag_id STRING COMMENT '标签唯一标识,如 tag_pay_amt_30d', tag_name STRING COMMENT '标签中文名,面向业务方展示', tag_type STRING COMMENT '事实类 / 规则类 / 模型类', calc_rule STRING COMMENT '计算规则描述,与SQL实现保持同步', update_cycle STRING COMMENT '更新周期:daily / weekly / monthly', owner STRING COMMENT '口径责任人', status STRING COMMENT 'online / offline' );

标签值单独存一张表,按日期分区,一个用户一个标签一行。这张表会很大,所以只存「当前有效」的标签值,历史值按需归档。圈选时不直接查标签值表,而是查宽表,因为宽表已经把高频标签打平,查询快得多。

-- 人群圈选:近30天有下单、累计金额达标、且近30天几乎不活跃的召回人群 SELECT w.user_id FROM ads_user_wide_1d w WHERE w.dt = '${bizdate}' AND w.order_cnt_30d >= 1 AND w.pay_amt_30d >= 200 AND w.active_days_30d <= 1 AND w.user_id NOT IN ( -- 频控:排除近7天已触达过的用户 SELECT user_id FROM ads_marketing_touch_log WHERE dt >= date_sub('${bizdate}', 7) );

圈选逻辑里有三个坑要提前处理:第一,必须做频控,否则同一批用户一周被短信轰炸五次,投诉率会很难看;第二,圈选结果要落快照表,不能每次重算,否则同一活动两次圈出的人群不一致,效果没法归因;第三,人群规模要有上下限,太小的群体跑不出统计显著性,太大的群体触达成本失控。

4.3 应用层落地:人货场看板、自助分析与自动化营销

应用层按使用对象分三类。面向内部运营和产品,核心是「人货场」三张看板:用户分析看新增、活跃、留存、分层流转;商品分析看动销率、库存周转、爆款生命周期;流量分析看渠道来源、页面路径、转化漏斗。面向管理层,是交易大盘看板,关注 GMV、客单价、退款率、各产品线贡献占比,指标要少而稳,一周内不要改口径。面向商家或外部,是行情报告和店铺诊断,数据要脱敏,粒度要粗。

自助分析平台解决的是「业务方提需求、数据团队排队」的老问题。做法是把指标和维度做成可配置项,业务方拖拽生成看板,数据团队只维护指标层和权限。这里的关键约束是:自助分析只能用已注册的指标,不允许业务方自己写 SQL 定义新指标,否则口径立刻失控。看板配置要支持千人千面,每个人只看到自己权限范围内的数据。

自动化营销平台把「圈人、选渠道、发内容、收效果」串成闭环。策略用配置描述,不写死在代码里。

{ "activity_id": "act_coupon_recall_01", "crowd": { "source": "ads_user_wide_1d", "rule": "order_cnt_30d>=1 and pay_amt_30d>=200 and active_days_30d<=1", "limit": 50000 }, "channel": ["sms", "push"], "frequency": { "window_days": 7, "max_times": 1 }, "content": { "template_id": "tpl_coupon_20", "coupon_id": "cp_20_off_100" }, "schedule": { "start": "2024-06-01", "end": "2024-06-07", "send_time": "10:00" } }

配置里rule直接复用宽表字段,保证圈选口径和看板口径一致;frequency是频控,必须配,不配就是给自己埋雷;schedule把活动周期固定下来,活动结束后自动停止,避免忘记关停导致持续发送。活动跑完,效果回流到中台:触达人数、领取率、核销率、带来的 GMV,统一进活动效果表,下一轮策略基于这些数据调整。

推荐平台属于更上一层的数据智能应用。离线部分做召回和排序,基于用户画像和商品特征生成候选集;实时部分补上会话内行为,用户刚浏览的品类要在下一次请求里体现。推荐效果依赖标签质量和宽表新鲜度,标签更新滞后一天,推荐就会推昨天买过的东西,这是最常见的体验事故。

5. 常见问题排查:五类最容易翻车的环节与处理办法

中台项目上线不等于成功,真正的考验在上线后三个月。下面五类问题几乎每个项目都会遇到,写出来是为了让后来的人少走弯路。

5.1 指标对不上:同名不同口径

现象:同一个「活跃用户数」,看板、报表、导出文件三个数字,差异能到 20%。

原因:定义时只写了指标名,没写清口径。「活跃」可能指登录、可能指有行为、可能指有交易;时间窗口可能含当天也可能不含;去重是按用户还是按设备也没说。三个团队各按自己的理解写 SQL,数字当然对不上。

解决:建指标字典,强制五要素齐全,新增指标必须走评审。发现不一致时,不要开会吵,直接把三份 SQL 拉出来对比 WHERE 条件,差异通常就在一两行过滤上。修完之后把这次差异写进指标变更记录,作为后续培训材料。

5.2 埋点漏报与重复上报

现象:某天某个渠道的新增用户突然翻倍,或者某页面转化率异常偏低。

原因:漏报通常是发版时埋点代码被覆盖,或者 SDK 初始化失败;重复上报多半是页面重复挂载、上报队列重试没做幂等。这两种问题在客户端都不报错,属于静默失败。

解决:埋点要有校验机制。前端做本地日志采样,后端按event_id + user_id + 时间戳做幂等去重。每天跑一个埋点健康度任务,对比各事件的昨日量与 7 日均值,波动超过阈值就告警。发版流程里加一步埋点回归,重点页面必须过一遍。

5.3 标签口径漂移与更新滞后

现象:运营反馈圈出来的人群「不对」,明明选的是高价值用户,推过去转化率极低。

原因:标签定义改了但计算任务没改,或者任务失败没人发现,标签值停留在三天前。更隐蔽的一种是宽表快照日期取错,用了前天的分区,圈出来的是过期人群。

解决:标签定义表里的calc_rule必须和实际 SQL 保持同步,改一处必须改两处。每个标签任务配数据质量监控:产出分区是否存在、行数波动是否超过阈值、空值率是否异常。圈选结果落快照时带上数据日期,营销系统发送前校验日期,超过 24 小时就拒绝执行。

5.4 看板建完没人用

现象:自助分析平台上线,配置了上百个看板,一个月后访问日志里只有个位数用户。

原因:建看板的人不懂业务,业务方真正关心的指标没进平台;或者查询太慢,点开要等半分钟;或者权限申请流程太长,业务方放弃了。

解决:上线前先找三到五个真实业务角色做场景验证,让他们说出每天必看的三个数字,先把这三个做快做准。查询性能靠 ADS 层预聚合解决,不做实时查询。权限按角色预置,默认开通本部门数据,跨部门走审批但限时 24 小时。

5.5 调度失败无人知

现象:早上开会,大屏数据是昨天的,或者某个指标直接空白。

原因:任务依赖没配全,上游延迟导致下游空跑;或者失败告警发到一个没人看的群;或者任务重跑后数据重复写入,数字翻倍。

解决:所有核心任务配三级告警,失败、延迟、数据量异常各一条,告警发到值班人而不是群。写入统一用分区覆盖而不是追加,天然幂等,重跑不会翻倍。每天早八点跑一次核心链路巡检,把结果推给中台负责人,这条巡检习惯能省掉大量早会尴尬。

注意:这五类问题里,前四类都能靠规范和监控解决,第五类必须靠流程。技术手段解决不了「没人看告警」这件事。

6. 验收与答辩:用三条证据链证明中台真的在跑

验收不看功能清单,看证据。我一般准备三条链:口径链、时效链、应用链。

口径链是拿三个核心指标,从 ADS 结果一路倒推到 ODS 原始记录,现场演示同一条订单在每一层的样子,证明数字可追溯。时效链是拉出近 30 天的任务执行记录,统计核心任务的成功率和产出时间,给出 p95 延迟,证明数据是按时到的。应用链最有说服力,选一个真实业务场景,比如一次召回活动,展示人群怎么圈、触达怎么发、效果怎么回流,用转化率说明这套链路产生了业务价值。

验收项证据形式合格线(经验值)
指标一致性三个指标的全链路倒推演示与业务方手工核对无差异
任务稳定性近 30 天执行记录核心任务成功率 99% 以上
数据及时性产出时间分布核心表每日 8 点前可用
应用渗透看板周活、自助分析使用人数目标用户覆盖过半
标签可用性圈选人群与人工抽样比对准确率 90% 以上

答辩时最容易犯的错是从技术栈开始讲,讲了一堆组件,评委不知道你到底解决了什么问题。更好的顺序是:先讲为什么判断这家公司需要中台(业务密度、数据孤岛的具体表现),再讲四层链路怎么分工,最后落到一个业务结果上,比如沉睡用户召回带来的增量交易。技术细节留到提问环节,评委问到再展开,问到哪层答哪层,答不上来的直接说这块是后续规划,比硬编强。

还有一个细节:提前把演示环境的数据准备好,别现场跑查询。我见过太多答辩现场卡在查询超时上,气氛一下就凉了。所有演示结果提前落成截图或固定报表,现场只做讲解。

从那以后我每次带项目走到验收这一步,都会强制走一遍这三条链,哪怕时间再紧也不省。因为验收不是给评委看的,是给自己看的——链路能不能倒推、任务稳不稳、业务用不用,这三件事答不上来,项目就不算完。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进