数据仓库设计
问题
如何设计一个规范的数据仓库?有哪些设计原则和规范?
答案
主题域划分
数仓按业务主题组织数据,每个主题域包含相关的事实表和维度表:
| 主题域 | 包含内容 | 示例表 |
|---|---|---|
| 用户域 | 用户注册、登录、画像 | dwd_user_register、dim_user |
| 交易域 | 下单、支付、退款 | dwd_trade_order、dwd_trade_payment |
| 流量域 | 页面浏览、点击、搜索 | dwd_traffic_page_view |
| 营销域 | 优惠券、活动、推广 | dwd_marketing_coupon |
| 商品域 | 商品上下架、库存 | dim_product、dwd_product_stock |
命名规范
{层级}_{主题域}_{数据域}_{描述}_{粒度}
示例:
ods_trade_order -- ODS 层交易域订单
dwd_trade_order_detail -- DWD 层交易域订单明细
dws_trade_user_daily -- DWS 层交易域用户日汇总
ads_trade_dashboard -- ADS 层交易看板
dim_product -- 维度层商品维度
宽表设计
DWS/ADS 层的宽表是多张表 JOIN 后的"胖表":
用户宽表设计示例
CREATE TABLE ads_user_profile AS
SELECT
u.user_id,
u.register_date,
u.city,
-- 交易特征
t.total_orders,
t.total_amount,
t.last_order_date,
-- 活跃特征
a.login_days_30d,
a.page_views_7d,
-- 偏好特征
p.top_category,
p.avg_price_range
FROM dim_user u
LEFT JOIN dws_trade_user_summary t ON u.user_id = t.user_id
LEFT JOIN dws_active_user_summary a ON u.user_id = a.user_id
LEFT JOIN dws_user_preference p ON u.user_id = p.user_id;
宽表的权衡
| 优点 | 缺点 |
|---|---|
| 查询快(无 JOIN) | 更新成本高(依赖多张上游表) |
| BI 友好 | 冗余存储 |
| SQL 简单 | 灵活性差(加字段需改结构) |
数仓建设原则
| 原则 | 说明 |
|---|---|
| 一致性 | 同一指标全仓只有一个口径 |
| 复用性 | DWD/DWS 被多个 ADS 复用 |
| 可扩展 | 新增业务不影响已有结构 |
| 分层清晰 | 每层职责明确,禁止跨层引用 |
| 数据质量 | 每层有质量校验规则 |
常见面试问题
Q1: 你们的数仓是怎么建的?整体架构是什么?
答案(标准回答框架):
- 分层:ODS → DWD → DWS → ADS + DIM
- 主题域:按业务划分(用户、交易、流量、营销)
- 建模方式:DWD/DWS 用维度建模(星型模型),ADS 用宽表
- 工具链:数据采集用 Canal/Flume → 存储 Hive/ClickHouse → 调度 Airflow → BI 出数
Q2: 宽表和维度模型怎么选?
答案:
- DWD/DWS 层:用维度模型(星型),保持灵活性和复用性
- ADS 层:用宽表,面向特定查询场景,性能优先
- 原则:越底层越灵活(维度模型),越上层越面向应用(宽表)
Q3: 如果有一个新的数据需求,你的开发流程是什么?
答案:
- 理解需求:和业务确认指标口径、维度、粒度
- 查现有资源:DWD/DWS 有没有可复用的表?
- 评估影响:需不需要新建 DWD?还是只需在 ADS 层加一张表?
- 开发:按层级从下往上(ODS → DWD → DWS → ADS)
- 质量验证:数据校验、和业务方核验
- 上线:配置调度、文档、监控