订阅更新

数仓分层讲了半天面试官说"太教科书了":怎么讲出自己的思考

项目实战表达 13 讲 · 第 11 讲 约 20 分钟读完

本文目录
  1. 开篇:一句"太教科书了"毁掉的面试
  2. 先说结论
  3. 教科书回答 vs 有思考的回答
  4. 完整示范:我怎么讲"为什么没有 DWS 层"
  5. 每一层可以讲出深度的点
  6. 进阶技巧:怎么让你的分层讲得"有趣"
  7. 面试回答分层——60 vs 75 vs 90 分
  8. 面试高频追问
  9. 总结
  10. 下一篇

开篇:一句"太教科书了"毁掉的面试

前阵子一个朋友跟我吐槽他的面试经历——

面试官让他讲数仓分层,他讲得很"完整"——

"我们数仓分为四层:ODS 原始层、DWD 明细层、DWS 汇总层、ADS 应用层。

ODS 层负责存储原始数据,不做任何处理,保留原始粒度; DWD 层负责清洗、去重、维度关联,生成明细数据; DWS 层基于 DWD 层按主题做聚合,产出宽表; ADS 层直接对接应用层,产出报表和 API 所需的结果。

我们用的是 Kimball 方法论,主要基于星型模型建模……"

讲了 5 分钟,面试官打断了他:

"你讲的这些太教科书了——和其他候选人讲的一模一样。能不能讲点你们自己的东西?"

朋友愣住了——"我们的东西就是这样的啊?"

那轮面试后他挂了。面试官的评语是——"表达能力有,但缺乏实战深度和独立思考。"


他跟我吐槽的时候说:"我真的是按标准四层分的啊,我有什么好讲的?"

我反问他:

  • 你的 DWD 层有没有做什么特殊处理?(字段映射?跨时区?)
  • 你的 DWS 层是不是真有必要?(还是可以省掉?)
  • 你为什么选星型模型不选雪花?
  • 某个指标口径你们是怎么统一的?
  • 数据质量问题你们踩过什么坑?

他想了想,突然说——"好像是有一些,但我觉得都是常规做法,不值得讲。"

这就是最大的误区——"常规做法不值得讲"完全是错的。面试官听过 100 个候选人讲数仓分层,他们都在背同样的教科书定义。你的"常规做法"在他眼里就是差异化——因为你有具体场景、具体决策、具体问题,教科书没有。


面试官听到"ODS 原始层、DWD 明细层、DWS 汇总层、ADS 应用层"的开场,心里已经自动打了个哈欠——这是所有候选人的标准开场。差异化的开场应该是——

"我们的数仓其实只有三层,没有独立的 DWS 层,这个决策是基于我们业务的特殊性……"

—— 这句话面试官立刻会坐直身体听下去。因为他听到了'你的思考',而不是'教科书的定义'。


这篇我会讲透怎么把数仓分层讲出自己的思考——

  • 三个方向让你的分层讲得不教科书:与标准不同 / 具体设计决策 / 业务价值
  • 每一层可以讲出深度的点:ODS / DWD / DWS / ADS 各层的"非教科书讲法"
  • 完整示范:我怎么讲"为什么某短剧出海公司的数仓只有三层"
  • 高频追问:命名规范、数据血缘、分层 vs 分域

看完这篇你能做到——同样是数仓分层这道题,别人讲 30 秒就暴露背书本质,你讲 3 分钟面试官全程追问你的设计思路。


先说结论

讲分层要讲"为什么"不只讲"是什么"。

三个方向让你的分层不教科书:

  1. 讲你的分层和标准有什么不同——多了什么?少了什么?为什么?
  2. 讲某一层的具体设计决策——为什么 DWD 层做了 XX 特殊处理?
  3. 讲分层带来的业务价值——分层前后的对比?解决了什么具体问题?

核心心法:教科书讲"数仓应该这样分",你要讲"我的数仓为什么这样分"。把"应该"换成"为什么",就从 0 分升到 90 分。


教科书回答 vs 有思考的回答

先对比几组——让你直观感受差别:

问题 教科书回答(0分) 有思考的回答(满分)
你们分几层? "ODS/DWD/DWS/ADS 四层" "我们只分了三层没有独立 DWS——因为业务指标变化快,预聚合容易过时"
ODS 层做什么? "存储原始数据" "ODS 层我们做了格式统一——5 个广告平台的字段名/类型/时区全部标准化,下游不用管原始差异"
DWD 层怎么设计? "清洗明细数据" "DWD 层最大的设计是跨平台字段映射——Facebook 叫 spend、TikTok 叫 cost、Google 叫 cost_micros,我统一成 ad_cost,单位统一美元"
为什么用星型模型? "星型模型查询快" "维度表都很小(最大 50 万行),JOIN 开销可接受,比雪花少一层 JOIN,分析师用起来更简单——这是为分析师友好度做的设计"
DWS 层怎么设计? "按主题建汇总表" "我只对最高频的 5 个维度组合做预聚合,覆盖 80% 查询。剩下 20% 长尾查询回退到 DWD 现场计算——避免维度组合爆炸"
ADS 层做什么? "对接应用层" "ADS 层不只是产出报表——还包括数据推送:核心指标每天凌晨推飞书群自动日报,异常指标(CPA 波动 20%+)触发即时告警。ADS 是数据和业务的最后一公里"
指标口径怎么管? "统一计算逻辑" "GMV 之前有两个口径——运营用的含退款版本、财务用的不含退款版本,差了 15%。我拉了跨团队评审会,最终定义 gmv_standard 为不含退款,另建 gmv_gross 供运营看毛收入"

对比看出的规律——

  • 教科书回答是名词 + 动词("ODS 存储原始数据")
  • 有思考的回答是场景 + 决策 + 权衡 + 效果("因为 XX 所以我们做了 YY,牺牲了 ZZ 换来 WW")

完整示范:我怎么讲"为什么没有 DWS 层"

这是我面试最常被追问深挖的一段——完整讲 3 分钟,面试官全程在追问。

场景设定

"某短剧出海公司的广告数据数仓——5 个广告平台(Facebook/TikTok/Google/AppLovin/UnityAds)的投放数据统一分析。核心业务问题——广告投放的指标需求变化非常快。

这周要看 CPA(单次获客成本) 下周要看 LTV(用户生命周期价值) 再下周要看 7 日 ROAS(广告支出回报率) 运营每周都有新的分析需求

这种场景下按标准的 DWS 层做预聚合合适吗?"

分析过程(讲给面试官听)

"我当时的分析:

按标准做法——DWS 层按高频维度组合预聚合:

  • dws_campaign_daily(按 campaign + 天)
  • dws_adgroup_daily(按 adgroup + 天)
  • dws_creative_daily(按 creative + 天)
  • dws_country_daily(按 country + 天)

问题——每加一个新指标要改 N 张 DWS 表(N 是维度组合数)。比如加个 '7 日 ROAS',要改 4 张 DWS 表、重跑 90 天历史数据。一周的工作量就这么耗掉了。

而且——运营临时想看'按素材类型 + 国家 + 投放时段' 的 ROAS,DWS 层没有这个组合,还是要现场聚合——那 DWS 层的价值在哪?"

我的设计决策(讲给面试官听)

"我的决策——没有独立的 DWS 层,只分三层:

ODS 层——5 个平台的 API 原始数据 DWD 层——做足了清洗和标准化:字段命名统一、单位统一、时区双字段、维度关联完成 ADS 层——直接基于 DWD 做聚合,用 Metabase 的自定义查询能力让运营自己拖拉拽

关键设计——DWD 层做得足够'厚':

  • 所有维度字段都直接冗余在 DWD(不用 JOIN 维度表)
  • 所有常用派生字段都预计算(比如 cpa = ad_cost / conversions)
  • 所有业务常量都枚举到位(比如周几、月份、时段)

这样 ADS 层直接 GROUP BY DWD 的任意字段组合就能出结果。"

Trade-off 明确(展示权衡思维)

"没有 DWS 的代价是什么?

代价 1:查询不够快——复杂聚合要扫 DWD 全量数据。

但我们的 DWD 日均只有几 GB(5 个平台总投放数据),用 MaxCompute 几秒就能跑完。这个代价可接受。

代价 2:热查询没有物化——同一个聚合被不同用户重复跑。

但 Metabase 有查询缓存,热查询第二次开始是毫秒级的。代价被工具抵消了。

什么时候我会重新引入 DWS?

如果数据量增长到 TB 级(比如业务扩到 20 个广告平台),DWD 全扫描超过 30 秒,就会引入 DWS 层做核心指标的物化视图——那个时候成本才值得。"

讲完后的面试官反应

"讲完这段,面试官追问了三个问题:

  1. '数据量到多大你会引入 DWS?'
  2. '预聚合和现场聚合的性能拐点在哪?'
  3. '运营自己写 SQL 你们怎么管控质量?'

这些追问说明面试官对我的回答感兴趣——他在跟我探讨技术选择,而不是审问背书。这就是讲出思考 vs 背书的区别。"


每一层可以讲出深度的点

ODS 层的深度点

教科书:

"ODS 层存储原始数据,不做任何处理,保留原始粒度。"

有思考的 3 个讲法:

讲法 1:格式统一

"ODS 不是简单的数据搬运——我们在 ODS 就做了数据格式标准化。5 个广告平台的 API 返回格式完全不同——有的 JSON、有的 CSV、有的嵌套结构、有的单条响应、有的批量数组。ODS 统一成 flat table 格式,下游处理一致。"

讲法 2:拉数策略

"ODS 的拉数策略很讲究——每小时拉当前数据 + 回溯 3 天的数据。因为广告平台有归因窗口期——用户今天看广告可能 3 天内下载 App,平台会追溯归因到最初看广告那天。所以今天拉的数据未来 3 天还会被修正。T+3 才算'最终数据'。"

讲法 3:分区设计

"ODS 的分区不是简单按 dt——是dt(数据日期)+ ingest_hour(入库小时)双层分区。这样既能按业务日期查询,又能按入库时间做数据追溯——发现异常时能精准定位是哪一次拉数的问题。"

DWD 层的深度点

教科书:

"DWD 层做清洗、去重、维度关联,生成明细数据。"

有思考的 3 个讲法:

讲法 1:跨平台字段映射

"DWD 最大的挑战是跨平台字段映射——同一个概念不同平台叫不同的名字。

  • 展示次数:Facebook 叫 impressions,TikTok 叫 shows,Google 叫 impressions
  • 广告花费:Facebook 叫 spend,TikTok 叫 cost,Google 叫 cost_micros(微单位)
  • 点击:Facebook 叫 clicks,TikTok 叫 link_clicks,Google 叫 clicks

我建了一个字段映射配置表——新增广告平台时只需要加映射规则,不用改代码。"

讲法 2:跨时区处理

"海外业务涉及美东/美西/欧洲/东南亚 4+ 个时区,我在 DWD 层做了双时间字段设计:

  • event_time_utc:UTC 原始时间(Source of Truth)
  • event_time_local:当地时间(按国家转换)

以及双分区:dt_utc(财务结算用)和 dt_local(运营报表用)。

这样'美国运营看昨天'和'中国运营看昨天'不会冲突——都是各自当地的昨天。"

讲法 3:幂等写入设计

"DWD 的主键设计是 (business_date, business_id) 复合主键,写入方式是 INSERT OVERWRITE 按分区覆盖——保证幂等。

为什么这样?——ODS 数据可能回溯修正(前面讲的归因窗口),DWD 需要支持重跑。用自增 ID 会导致重跑后主键变化,下游关联失效。用业务主键 + 分区覆盖是天然幂等的。"

DWS 层的深度点

教科书:

"DWS 层基于 DWD 按主题做聚合,产出宽表。"

有思考的 3 个讲法:

讲法 1:维度选择策略

"DWS 的设计关键是选择预聚合的维度组合——我们有 30+ 个维度但不能全部交叉聚合(组合爆炸:2^30 = 10 亿+组合)。

我选了 5 个最高频的维度组合做预聚合——基于前 3 个月的 Metabase 查询日志分析出来的。覆盖了 80% 的查询。剩下 20% 的长尾查询回退到 DWD 现场计算。

这就是 80/20 原则在数仓设计里的应用。"

讲法 2:更新策略

"DWS 的更新不是简单 INSERT OVERWRITE——是增量 MERGE。

比如 dws_campaign_daily 表,每天只更新最近 3 天的数据(归因窗口期内的数据会修正),历史数据不动。具体用 Delta Lake 的 MERGE INTO——写法比 UNION 精简 70%,性能也更好。"

讲法 3:物化视图探索

"我在考虑把部分 DWS 表改成物化视图——Delta Lake 和 Doris 都支持物化视图自动维护。

好处是 DWS 的维护成本降到零——物化视图根据 DWD 的变化自动刷新,不需要手动写 ETL。坏处是灵活性略降——物化视图的定义变更需要重建。

这是我 2024 年的重点方向之一。"

ADS 层的深度点

教科书:

"ADS 层对接应用层,产出报表和 API 所需结果。"

有思考的 3 个讲法:

讲法 1:ADS 不只是报表

"ADS 层不只是产出报表——还包括数据推送。

  • 核心指标 每天凌晨推送到飞书群,自动生成日报(运营不用登录 BI 系统)
  • 异常指标(CPA 波动 20%+)触发即时告警到风控群
  • 高管视角指标每天早 8:30 推送邮件摘要给 CEO/COO

ADS 层是数据和业务的最后一公里——它决定了数据能不能真正被用起来。"

讲法 2:服务分级

"ADS 层我分成了三级服务:

  • L1 核心看板(DAU/GMV/ROAS)—— 高可用、SLA 99.9%、故障 30 分钟内响应
  • L2 业务报表(运营日报、产品周报)—— SLA 99%、故障 2 小时响应
  • L3 探索分析(临时分析需求)—— 不保 SLA、尽力而为

这样运维精力按优先级分配——核心看板永不挂,探索分析偶尔慢是正常的。"

讲法 3:ADS 的质量保障

"ADS 的数据最怕'看起来正常但实际错了'——比如 DAU 突然从 100 万变成 50 万,系统没报警但业务方发现了。

我在 ADS 层加了三层质量校验:

  • 数值边界校验(DAU 日环比波动 >50% 触发)
  • 趋势一致性校验(和同环比模型对比)
  • 跨数据源对账(ADS 的 GMV 对比订单系统的 GMV)

这三层校验比简单的'行数不为空'有价值得多。"


进阶技巧:怎么让你的分层讲得"有趣"

除了讲思考深度,还可以用"故事"让分层讲得有温度。

技巧 1:用"历史包袱"讲分层演进

平铺直叙:

"我们数仓分四层。"

有历史感:

"我们数仓最早只有两层——一层原始数据一层汇总数据,下游直接用汇总层做报表。运行一年后问题暴露了:

  1. 脏数据直接污染报表(原始层的 NULL、格式问题没清洗)
  2. 多张汇总表重复计算维度关联(浪费计算资源)
  3. 口径不一致(不同汇总表对同一指标定义不同)

我用了 3 个月做分层重构——加了 DWD 层做防火墙,DWS 层做主题聚合,ADS 层专注应用。重构后数据质量问题减少 60%,查询性能提升 3 倍。

所以分层不是'天生应该四层'——是业务问题逼出来的必然选择。"

技巧 2:用"踩坑故事"讲某一层

平铺直叙:

"DWD 层做了数据清洗。"

有血有肉:

"DWD 层的清洗我踩过一个大坑——以为数据是'干净'的,结果爆雷。

有次运营投诉 ROAS 数字不对——某个 campaign 的 ad_cost 显示 0。我排查 DWD 数据是对的,ODS 数据也是对的,只有运营看到的 ADS 结果是错的。

最终定位——某个 Facebook API 在特定广告类型下返回 spend = "0.0" (字符串 0),我的 DWD 清洗只处理了数字 NULL,没处理字符串 "0",导致数据类型转换报错。

修复后我在 DWD 加了三类兜底清洗——NULL、空字符串、类型不匹配——任何一类都能触发告警。这个坑之后再没出过类似问题。"

技巧 3:用"业务价值"讲最后的意义

纯技术讲:

"我们分层清晰、命名规范。"

业务价值讲:

"分层清晰带来的真实业务价值——运营从'每周等我们出数据' 变成 '自己在 Metabase 拖出想要的分析'。

具体数字——

  • 运营的分析自主度从 30% 提升到 80%
  • 数据需求排队等待从平均 3 天降到 4 小时
  • 我每周的临时分析请求从 10+ 个降到 1-2 个

我的时间被释放出来做更有价值的事(数据治理、架构优化、技术分享)。

分层清晰的终极价值不是技术漂亮,是解放人力、赋能业务。"


面试回答分层——60 vs 75 vs 90 分

60 分回答(教科书复读)

"我们数仓分四层:ODS 存储原始数据、DWD 做明细清洗、DWS 做主题聚合、ADS 产出报表。用了星型模型,Kimball 方法论……"

面试官内心OS:"又一个背书的。下一个。"

75 分回答(有结构但浅)

"我们数仓分四层。ODS 层接入了 5 个广告平台的数据。DWD 层做了字段标准化,把不同平台的字段名统一了。DWS 层按广告维度做了聚合。ADS 层产出了业务报表……"

面试官内心OS:"有一些自己的内容,但都是'做了 XX' 的陈述,没有'为什么这样做'的思考。"

90 分回答(讲思考)

特征:

  • 讲'和标准不同'("只分三层没有 DWS")
  • 讲'具体设计决策'("跨平台字段映射 + 跨时区双字段")
  • 讲'trade-off'("不做 DWS 的代价是什么,什么条件下会引入")
  • 讲'业务价值'("运营分析自主度从 30% 到 80%")
  • 留'钩子'引追问("这是 80/20 原则在数仓的应用")

面试官内心OS:"这人真想过数仓架构——不是跟着教科书做。可以讨论更深的话题。Top 10% 候选人。"


面试高频追问

追问 1:你们的命名规范是什么?

这题答好可以直接拉开差距——很多人没认真想过命名规范。

加分回答:

"表名规则:{层}_{业务域}_{主题}_{周期}

  • dwd_ads_campaign_daily:DWD 层 / 广告域 / campaign 主题 / 日表
  • dws_ads_creative_weekly:DWS 层 / 广告域 / creative 主题 / 周表
  • ads_ads_roi_report:ADS 层 / 广告域 / ROI 报表

字段名规则:{实体}_{属性}

  • user_id、campaign_name、ad_cost、conversion_count

维度表和事实表前缀区分:

  • dim_ 前缀:dim_user、dim_campaign
  • fact_ 前缀:fact_order、fact_ad_event

时间字段统一:

  • created_at / updated_at(DateTime 类型)
  • dt 分区字段(String 类型 YYYYMMDD)
  • event_time_utc / event_time_local(双时间)

规范落地机制:

  1. 规范写在 Confluence Wiki 上,每个新表的 Code Review 必须检查命名
  2. 自动化校验——用 SQL 解析工具检测新表名,不符合规范拒绝建表
  3. 定期审计——每季度扫描一次存量表,不规范的标记清理

命名规范看似小事,但在 100+ 张表的数仓里是'大事'——命名清晰让分析师、运营、新同事都能快速理解表的含义,减少了大量沟通成本。"

追问 2:数据血缘怎么追踪?

血缘是数据治理的核心能力——答好能展示你的治理意识。

加分回答:

"血缘分两层:

表级血缘——能看到每张表的上下游表

  • MaxCompute / Databricks 自带表级血缘(通过 SQL 解析实现)
  • 每张表跑完自动记录 Source 表和 Target 表
  • 可视化展示为 DAG 图

字段级血缘——能看到某个字段的数据流向

  • 我们用 SQLLineage 工具(开源,基于 Python 和 SQLFluff)
  • 解析 SQL 的 SELECT 子句,追踪每个字段的来源字段
  • 展示为字段级别的血缘图

血缘的核心价值是影响分析——

场景 1:上游字段要改。比如 DWD 的 ad_cost 字段要调整精度(DECIMAL(18,4) → DECIMAL(20,6))——血缘工具能列出所有受影响的下游表和报表(20+ 张),一一通知业务方评估影响,避免'改完才发现报表挂了'。

场景 2:数据异常排查。ADS 报表数字不对——反向追溯血缘,从 ADS → DWS → DWD → ODS 找到源头。原本要排查半天,有了血缘 5 分钟定位。

场景 3:数据下线决策。想下线某张 DWS 表——先看血缘没有下游引用才能下线。避免下线后业务方投诉。

血缘是看似不重要但关键时刻救命的基础能力。"

追问 3:分层和分域有什么关系?

这题考你的数仓架构整体认知。

加分回答:

"分层是纵向的,分域是横向的——形成一个二维矩阵。

纵向分层(ODS → DWD → DWS → ADS):按数据加工的阶段划分

横向分域:按业务领域划分——

  • 用户域(user)
  • 交易域(order)
  • 广告域(ads)
  • 内容域(content)
  • 设备域(device)

每个域在每层都有自己的表:

广告域:
├─ ods_ads_facebook_raw
├─ dwd_ads_campaign_daily  
├─ dws_ads_creative_weekly
└─ ads_ads_roi_report

用户域:
├─ ods_user_login_raw
├─ dwd_user_profile
├─ dws_user_retention_daily
└─ ads_user_dashboard

分域的好处:

  1. 责任清晰——广告域的表归广告团队管、用户域的归用户团队管。跨团队协作有明确边界
  2. 互不影响——广告域改个字段不影响用户域
  3. 权限控制——可以按域做读写权限管理(广告团队读用户域需申请)

分层和分域组合起来——一张表的位置用{层}_{域}_{主题}_{周期}精准定位,任何人看到表名就知道它是谁的、做什么、什么粒度。

小公司可以只分层不分域(数据量小、团队小)、中大公司必须分层+分域双维度(规模大、团队多、权限复杂)。"

追问 4:你们有没有数据仓库建设的 SOP?

展示你的工程规范意识。

加分回答:

"有,而且我自己写的。《数据仓库建设 SOP》覆盖 6 个环节:

1. 需求评审环节:新数仓需求来了怎么评估优先级、怎么排期

2. 建模设计环节:

  • 先画业务流程图
  • 再设计事实表和维度表
  • 确认缓慢变化维策略(Type1/2/4)
  • 评审建模方案

3. 命名规范环节:表名/字段名/分区字段按规范执行

4. 代码开发环节:

  • SQL 必须有注释(业务逻辑、字段含义)
  • INSERT OVERWRITE 强制用(不允许 INSERT INTO 避免重跑问题)
  • 禁止 SELECT *
  • Code Review 必过 Checklist

5. 质量校验环节:

  • 上线前必须配置 DQC(数据质量检查)
  • 至少覆盖:行数、核心字段 NULL 率、核心指标同环比

6. 上线运维环节:

  • 调度依赖关系明确
  • 失败告警到值班群
  • SLA 分级(L1/L2/L3)

SOP 是数仓从'个人能力'变成'团队能力'的关键——没有 SOP,每个人按自己习惯做,几个人的团队很快混乱。有了 SOP,新人入职 1 周能独立建表,不用每次都问。

这套 SOP 也是我面试时能讲的'方法论产出'之一——不只是我做了项目,我沉淀了方法。"


总结

"讲出自己的思考"是数仓面试拉开差距的最关键能力——核心要点——

  • 三个方向让分层不教科书:
    1. 讲和标准不同的地方("我们只有三层没有 DWS")
    2. 讲具体设计决策(字段映射 / 维度选择 / 命名规范)
    3. 讲 trade-off("没有 DWS 的代价是什么,什么条件下会引入")
  • 每层都有可讲的深度点:
    • ODS:格式统一 / 拉数策略 / 分区设计
    • DWD:跨平台字段映射 / 跨时区处理 / 幂等写入
    • DWS:维度选择 / 更新策略 / 物化视图
    • ADS:不只是报表 / 服务分级 / 质量保障
  • 3 个讲"有趣"技巧:
    1. 用历史包袱讲分层演进("从两层进化到四层的过程")
    2. 用踩坑故事讲某一层("Facebook 返回字符串 0 的坑")
    3. 用业务价值讲最后的意义("运营自主度 30% → 80%")
  • 命名规范、数据血缘、分层+分域——每个都是面试的深度加分项,准备好答案
  • 有 SOP 意识——从'我做了项目'到'我沉淀了方法'是高级工程师的分水岭
  • 面试策略:教科书是大家共有的 0 分底线,你的思考是 90 分的差异化。任何时候记住——面试官已经听过 100 个'ODS/DWD/DWS/ADS'了,他期待的是第 101 个候选人讲出不一样的东西

下一篇

刷题进度保存在当前浏览器