本章目标:把前四章建好的数仓变成能投递的作品:一份 README、一份分析报告、一份质量报告、一段 3 分钟讲述、三条不夸大的简历 bullet。 前置知识:已完成 01–04,实验室库和
quality_report_lab.md都已产出。 预计用时:90 分钟(写 + 改 + 录一遍)。
0. 本章你要产出什么
| 交付物 | 位置 | 完成标准 |
|---|---|---|
| 项目 README | project/README.md(从 project/README模板.md 改写) |
30 秒能说清是什么、怎么跑、结果多少 |
| 分析报告 | project/analysis_report.md |
六段结构,每条结论都有数字 |
| 质量报告 | project/quality_report_lab.md(04 章产出) |
行数、指标、异常、分级齐全 |
| 3 分钟讲述 | 录音或提纲 | 不看稿讲完,主动说局限 |
| 简历 bullet | 简历草稿 | 3 条,都有数字,无“精通/生产级” |
| GitHub 仓库 | 本地目录 + .gitignore |
不含原始数据、数仓文件和 lab 库 |
完成标志:找一个没看过项目的人,只读 README 就能跑起来;你自己能不看稿讲 3 分钟,并回答 5 个追问。
1. 交付物清单
| 交付物 | 位置 | 面试作用 |
|---|---|---|
| 数据说明 | data/README.md |
证明数据来源、许可、局限 |
| 标准答案 | data/metrics.json |
证明指标可复现 |
| 构建脚本 | project/build_warehouse.py |
证明能一键跑通 |
| 实验室脚本 | project/run_sql.py、project/lab/01_ods.sql |
证明是自己一步步建的 |
| 分层 SQL | project/sql/*.sql |
证明建模和口径 |
| ADS 结果 | project/ads/*.csv |
证明有输出 |
| 质量报告 | project/quality_report_lab.md |
证明做过对账 |
| 分析报告 | project/analysis_report.md |
证明能解释结果 |
| 项目 README | project/README.md |
证明会交付 |
没有质量报告、分析报告和 README,项目在面试里只是一堆 SQL 文件。
2. 动手一:写 README
2.1 先自己写,再对照模板
不要直接复制。先拿一张纸回答四个问题,再打开 project/README模板.md 对照:
- 项目用的是什么数据,多大,什么时间范围?
- 别人拿到仓库后,按什么顺序能跑起来?
- 四层各产出什么表,核心数字是多少?
- 有哪些口径容易误解,有哪些局限?
2.2 README 结构
按“是什么 → 怎么跑 → 结果 → 口径 → 局限”组织,控制在 80 行以内:
# Olist 电商数仓
基于 Olist 巴西电商公开数据集(8 张表 / 550,759 行)的四层数仓项目。
本地用 DuckDB 一键复现,附数据体检、指标对账和 ADS 结果。
## 1. 数据集
- 来源:Kaggle Olist Brazilian E-Commerce
- 许可:CC BY-NC-SA 4.0,仅学习使用
- 时间:2016-09-04 ~ 2018-10-17
- 分析窗口:2017-01 ~ 2018-08
## 2. 快速开始
```bash
# 先按 00 章第 4 节下载数据集,解压到 data/raw/olist/
python scripts/check_data.py
python project/build_warehouse.py
python scripts/check_sql.py
```
想按教程从零建一遍,用 `project/run_sql.py` 和 `project/lab/01_ods.sql`,
实验室库 `project/warehouse_lab.duckdb` 不提交。
## 3. 架构
CSV → ODS(8) → DWD(2) → DWS(6) → ADS(8)
## 4. 核心结果
| 指标 | 数值 |
|---|---:|
| GMV(含运费) | 15,740,216.93 |
| AOV | 160.29 |
| 复购率 | 3.04% |
| 迟到率 | 8.11% |
| 评价均分 | 4.09 |
## 5. 口径
- GMV = SUM(price + freight_value),仅有效订单
- AOV = GMV / 98,199 个有明细的有效订单
- 复购按 customer_unique_id 统计
- 迟到 = 签收时间 > 预计送达时间
## 6. 数据质量
- 441 单支付与明细差 >0.01,总差额 -1,851.52
- 1,234 单取消/不可用仍有支付,告警不判错
- 详见 project/quality_report_lab.md
## 7. 局限
- 没有数量字段,quantity 固定为 1
- 没有用户行为日志,不做 DAU/漏斗
- 数据止于 2018-10
参考答案:完整 README 模板
完整模板在 project/README模板.md,包含项目背景、数据源、快速开始、架构、ADS 结果、口径、质量、局限和目录结构。可以复制到 project/README.md 后按自己的实验室结果修改。
2.3 README 自查
- 30 秒内能看懂项目做什么;
- 快速开始四行命令能按顺序跑通;
- 核心结果有 5 个以上数字;
- 写清了 AOV 分母和复购 ID;
- 写了至少 3 条局限,没有把局限包装成优点。
3. 动手二:写分析报告
3.1 六段结构
报告不用长,六段足够:
- 背景与目标:为什么做、回答什么问题;
- 数据与口径:8 张表、时间窗口、指标定义;
- 整体表现:GMV、AOV、订单、买家、复购;
- 结构与趋势:月度、品类、卖家、RFM;
- 履约与评价:迟到率、履约时长、评分对比;
- 结论与局限:三条发现、三条限制、下一步。
3.2 结论要写成“数据 + 解释 + 动作”
不要只放数字。示例:
- 2017-11 GMV 1,173,387.01,环比 +53.41%,与大促时间吻合;
- Top 10 品类贡献 62.37%,长尾明显,选品不应只盯头部;
- 迟到订单评分 2.57,准时 4.29,履约体验是评分的关键抓手;
- 复购率 3.04%,RFM 无法筛出规模化的“重要价值客户”,需要结合业务判断。
3.3 交付
新建 project/analysis_report.md,把六段写全。至少包含:
- 一行核心结论(这个平台卖得怎么样);
- 一张月度 GMV 表或趋势描述;
- 一张品类 Top 5 表;
- 一组履约/评分对比;
- 三条局限。
自查:报告里最容易出现的四个问题
- 只有数字没有解释:每个数字后面补一句“说明什么”;
- 口径混用:窗口 GMV 和全量 GMV 不要混在一段;
- 把相关说成因果:迟到与低分只能说相关;
- 结论没有动作:至少给一条运营或数据建议。
4. 动手三:3 分钟讲述
4.1 时间分配
| 时间 | 内容 |
|---|---|
| 0:00–0:30 | 项目背景与数据 |
| 0:30–1:10 | 架构与建模 |
| 1:10–2:00 | 指标与结果 |
| 2:00–2:30 | 质量与难点 |
| 2:30–3:00 | 局限与下一步 |
4.2 讲稿
我做的是一个基于 Olist 公开电商数据集的四层数仓项目,数据是真实的巴西电商订单,8 张表、55 万行,时间从 2016 年 9 月到 2018 年 10 月。
架构是 ODS、DWD、DWS、ADS 四层。ODS 原样落 8 张表;DWD 建两张宽表,一张是订单 × 商品的明细表,一张是订单粒度宽表;DWS 按交易、品类、卖家、客户、履约六个主题聚合;ADS 输出 8 张结果表。
指标上,有效订单 98,207,有明细的订单 98,199,GMV 15,740,216.93,AOV 160.29,复购率 3.04%,迟到率 8.11%。所有指标都用 metrics.json 固定基线,构建脚本会自动对账。
难点主要在口径和边界:复购必须用 customer_unique_id,AOV 分母要排除无明细订单,评价和支付要先聚合再 JOIN,否则会 fan-out。质量上我做了 10 类检查,发现 441 单支付差异和 1,234 单取消单仍有支付,前者总差额 -1,851.52,后者作为告警不判错。
项目的局限是没有数量字段和行为日志,数据也止于 2018 年;我没有把它说成生产级数仓。下一步如果数据量放大,会把 DuckDB 换成 Hive/Spark,按天分区并做增量覆盖。
4.3 讲述注意
- 不要背数字,背“三个行数 + 四个指标”:98,207 / 112,101 / 98,199;GMV、AOV、复购率、迟到率。
- 主动说局限,比等人追问更加分。
- 不要把“跑了脚本”说成“独立负责生产数仓”。
- 讲“我踩过的坑”比讲“我用了什么技术”更有说服力,例如评价 fan-out、AOV 分母、支付口径。
4.4 录一遍,按清单自查
用手机录音,不看稿讲 3 分钟。回听后检查:
- 有没有把 AOV 分母说错;
- 有没有把复购说成按
customer_id; - 有没有把窗口 GMV 和全量 GMV 混用;
- 有没有把相关性说成因果;
- 有没有主动说局限;
- 3 分钟内能否讲完,不超时。
5. 动手四:简历 bullet
只写实际做过的,不写“精通”“独立负责”“生产级”。
- 基于 Olist 公开电商数据集(8 表 / 55 万行)搭建 ODS-DWD-DWS-ADS 四层数仓,
产出 2 张 DWD 宽表、6 张 DWS 主题表、8 张 ADS 结果表,DuckDB 一键复现。
- 统一 GMV/AOV/复购/履约口径,处理评价与支付的 fan-out;构建脚本自动对账
GMV 15,740,216.93、AOV 160.29、复购率 3.04%、迟到率 8.11%。
- 设计 10 类数据体检与质量报告,定位 441 单支付差异和 1,234 单取消单支付告警,
说明告警与错误的边界;如实披露无数量字段、无行为日志等数据局限。
不要写:
- “精通 Hive/Spark”(项目只做了语法级演示);
- “独立负责生产数仓”(没有生产环境);
- “6 类自动校验”这种模糊说法(实际是 10 类数据体检 + 40+ 项构建对账,直接说检查了哪些指标更可信)。
6. 动手五:GitHub 打包
6.1 仓库结构
olist-warehouse/
├── README.md
├── requirements.txt
├── data/
│ └── README.md
├── scripts/
│ ├── fetch_olist.py
│ ├── check_data.py
│ └── check_metrics.py
├── project/
│ ├── build_warehouse.py
│ ├── run_sql.py
│ ├── lab/
│ ├── sql/
│ ├── ads/
│ ├── analysis_report.md
│ ├── quality_report_lab.md
│ └── quality_report.md
└── docs/
6.2 .gitignore
data/raw/
project/warehouse.duckdb
project/warehouse_lab.duckdb
project/warehouse_lab.duckdb.wal
project/ads/*.csv
__pycache__/
*.pyc
原始数据 61 MB、数仓文件和 ADS 结果都可以重新生成,不提交。实验室库更是个人练习产物,不要提交。
6.3 提交信息
feat: 初始化 Olist 数据下载与体检
feat: 增加 ODS 贴源层与 DWD 明细宽表
fix: 修复评价 JOIN 导致的 fan-out
docs: 补充 AOV 分母口径说明
feat: 增加质量对账报告与分析报告
每次提交只做一件事,面试官点开 commit 能看懂思路。
7. 最终验收:从头再跑一遍
7.1 实验台路线:按顺序重建
如果实验室库已经乱了,删掉 project/warehouse_lab.duckdb,按下面 17 个脚本从头跑一遍。这就是 02–04 章的完整顺序,命令本身不用再翻章节:
python project/run_sql.py project/lab/01_ods.sql
python project/run_sql.py project/sql/dwd_order_detail.sql
python project/run_sql.py project/sql/dwd_order.sql
python project/run_sql.py project/sql/dws_trade_1d.sql
python project/run_sql.py project/sql/dws_trade_1m.sql
python project/run_sql.py project/sql/dws_category_1m.sql
python project/run_sql.py project/sql/dws_seller_1m.sql
python project/run_sql.py project/sql/dws_customer_rfm.sql
python project/run_sql.py project/sql/dws_service_1m.sql
python project/run_sql.py project/sql/ads_gmv_overview.sql
python project/run_sql.py project/sql/ads_month_trend.sql
python project/run_sql.py project/sql/ads_category_rank.sql
python project/run_sql.py project/sql/ads_seller_rank.sql
python project/run_sql.py project/sql/ads_customer_rfm.sql
python project/run_sql.py project/sql/ads_repurchase.sql
python project/run_sql.py project/sql/ads_delivery_sla.sql
python project/run_sql.py project/sql/ads_review_lateness.sql
跑完先确认表数和核心指标:
python project/run_sql.py -c "SELECT COUNT(*) AS table_cnt FROM information_schema.tables WHERE table_schema='main'"
python project/run_sql.py -c "SELECT (SELECT COUNT(*) FROM dwd_order_detail) AS detail_rows, (SELECT COUNT(*) FROM dwd_order) AS orders, (SELECT ROUND(gmv,2) FROM ads_gmv_overview) AS gmv, (SELECT repeat_rate_pct FROM ads_repurchase) AS repurchase_pct"
应为 24 张表、明细 112,101 行、订单 98,207 行、GMV 15,740,216.93、复购率 3.04%。
7.2 参考库路线:自动构建与对比
再跑一次自动构建,确认参考库也能复现:
# 先按 00 章第 4 节下载数据集,解压到 data/raw/olist/
python scripts/check_data.py
python project/build_warehouse.py
python scripts/check_sql.py
把实验室结果和参考库并排对一次:
ATTACH 'project/warehouse.duckdb' AS ref (READ_ONLY);
SELECT
(SELECT COUNT(*) FROM dwd_order_detail) AS lab_detail,
(SELECT COUNT(*) FROM ref.dwd_order_detail) AS ref_detail,
(SELECT COUNT(*) FROM dwd_order) AS lab_order,
(SELECT COUNT(*) FROM ref.dwd_order) AS ref_order,
(SELECT ROUND(SUM(gmv), 2) FROM dws_trade_1m) AS lab_window_gmv,
(SELECT ROUND(SUM(gmv), 2) FROM ref.dws_trade_1m) AS ref_window_gmv;
验收清单:
-
project/README.md能在 30 秒内说清项目是什么、怎么跑、结果多少。 -
project/analysis_report.md六段齐全,结论都有数字和解释。 -
project/quality_report_lab.md包含行数对账、指标对账、异常分级和处理结论。 - 实验室库与参考库的
dwd_order_detail、dwd_order、窗口 GMV 完全一致。 - 能在 3 分钟内讲完项目,不照读,并主动说局限。
- 能回答至少 5 个高频追问。
- 简历 bullet 没有“精通/独立负责/生产级”等夸大词。
-
.gitignore排除了原始数据、参考库、实验室库和生成文件。
8. 练习
练习 1:写 README
按本章模板写一份 README,要求包含数据集、快速开始、架构、核心结果、口径、局限六部分。
自测:一个没看过项目的人,能否只读 README 就把项目跑起来?
练习 2:写分析报告
基于你的 ADS 结果,写一份六段式分析报告,至少包含:
- 整体 GMV、AOV、订单、买家、复购;
- 月度趋势和 Top 5 品类;
- 履约与评分对比;
- 三条结论、三条局限。
练习 3:录 3 分钟讲述
用手机录音,不看稿讲 3 分钟。回听后按第 4.4 节清单逐项检查。
9. 面试延伸
面试题:你的项目和别人的数仓项目有什么不同?
是什么:多数课程项目用合成数据,本项目用公开真实数据,并且把质量和对账做进构建流程。
解决什么问题:真实数据有缺失、重复、时间倒挂和支付差异,能体现边界处理能力;自动对账让指标可复现,而不是“跑出来多少算多少”。
我的实操边界:项目规模小,没有生产调度、权限、数据血缘;优势是口径清楚、可本地复现、局限写得诚实。
面试题:如果让你把这个项目上线,你会补什么?
是什么:从本地脚本到生产数仓,需要补调度、存储、监控和权限。
解决什么问题:Airflow 调度、Hive/Spark 分区表、数据质量告警、元数据与血缘、权限管理;还要把全量覆盖改成增量。
我的实操边界:我只在本地跑通了全量构建,Hive 脚本未上集群;上线方案能讲清思路,但没有实际运维经验。