数据存储

第06课:数据仓库原理

数据工程实战课程 · 数据存储阶段

🏛️ 数据仓库原理

数据仓库是面向主题、集成、非易失、随时间变化的数据集合,由Bill Inmon于1990年提出。

🐍 Python实战:核心实战

# 维度建模与OLAP查询(SQLite实机)
import sqlite3, time, random
from datetime import datetime, timedelta

conn = sqlite3.connect(':memory:')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('CREATE TABLE dim_date (date_key INT PRIMARY KEY, full_date TEXT, year INT, quarter INT, month INT, day INT)')
c.execute('CREATE TABLE dim_product (product_key INT PRIMARY KEY, product_id TEXT, name TEXT, category TEXT, brand TEXT, price REAL)')
c.execute('CREATE TABLE dim_customer (customer_key INT PRIMARY KEY, customer_id TEXT, name TEXT, tier TEXT, region TEXT)')
c.execute('CREATE TABLE fact_sales (sale_key INTEGER PRIMARY KEY AUTOINCREMENT, date_key INT, product_key INT, customer_key INT, quantity INT, amount REAL, net_amount REAL, order_id TEXT)')

# 填充维度表
start_date = datetime(2024, 1, 1)
for i in range(365):
    d = start_date + timedelta(days=i)
    c.execute("INSERT INTO dim_date VALUES (?,?,?,?,?,?)", (int(d.strftime('%Y%m%d')), d.strftime('%Y-%m-%d'), d.year, (d.month-1)//3+1, d.month, d.day))

for i in range(100):
    cat = random.choice(['电子','服装','食品','家居'])
    c.execute("INSERT INTO dim_product VALUES (?,?,?,?,?,?)", (i+1, f"SKU_{1000+i}", f"产品_{i+1}", cat, f"品牌_{random.randint(1,10)}", round(random.uniform(10,5000),2)))

for i in range(500):
    c.execute("INSERT INTO dim_customer VALUES (?,?,?,?,?)", (i+1, f"CUST_{1000+i}", f"客户_{i+1}", random.choice(['standard','premium','vip']), random.choice(['华东','华南','华北','西南','东北'])))

# 填充事实表
for i in range(5000):
    qty = random.randint(1, 10)
    price = round(random.uniform(10, 5000), 2)
    discount = round(random.uniform(0, 0.3), 2)
    net = round(price * qty * (1-discount), 2)
    c.execute("INSERT INTO fact_sales (date_key,product_key,customer_key,quantity,amount,net_amount,order_id) VALUES (?,?,?,?,?,?,?)",
        (random.randint(20240101,20241231), random.randint(1,100), random.randint(1,500), qty, price*qty, net, f"ORD_{random.randint(10000,99999)}"))
conn.commit()
print(f"维度: 日期365, 产品100, 客户500 | 事实: 销售5000")

print("\n--- OLAP查询 ---")
print("\n按月销售:")
for row in c.execute("SELECT d.month, SUM(f.net_amount) total, COUNT(*) orders FROM fact_sales f JOIN dim_date d ON f.date_key=d.date_key GROUP BY d.month ORDER BY d.month LIMIT 6"):
    r = dict(row); print(f"  {r['month']}月: ¥{r['total']:,.0f}, {r['orders']}单")

print("\n按类别:")
for row in c.execute("SELECT p.category, SUM(f.net_amount) total FROM fact_sales f JOIN dim_product p ON f.product_key=p.product_key GROUP BY p.category ORDER BY total DESC"):
    r = dict(row); print(f"  {r['category']}: ¥{r['total']:,.0f}")

print("\n客户分层:")
for row in c.execute("SELECT c.tier, COUNT(*) cnt, SUM(f.net_amount) total FROM fact_sales f JOIN dim_customer c ON f.customer_key=c.customer_key GROUP BY c.tier"):
    r = dict(row); print(f"  {r['tier']}: {r['cnt']}单, ¥{r['total']:,.0f}")

print("\n季度对比:")
for row in c.execute("SELECT d.quarter, SUM(f.net_amount) total FROM fact_sales f JOIN dim_date d ON f.date_key=d.date_key GROUP BY d.quarter"):
    r = dict(row); print(f"  Q{r['quarter']}: ¥{r['total']:,.0f}")

print("✅ 验证通过 - 维度建模与OLAP运行正常")
💡 实战建议:动手实现本课代码示例,修改参数观察输出变化。生产环境还需考虑错误处理、监控告警和数据安全。

🎯 构建销售数仓

  1. 完整星型模型
  2. ODS→DWD→DWS→ADS
  3. 5个OLAP查询

🎯 缓慢变化维度

  1. SCD Type1/2/3
  2. 对比优劣

🏆 第6课成就解锁

🎁 下一课预告:数据湖架构!

📖 原理深入:现代数据存储架构

存储引擎选型指南

存储成本优化策略

策略原理节省比例
分层存储热SSD/温HDD/冷对象存储50-80%
数据压缩列式存储高压缩比60-90%
生命周期自动归档删除30-60%
降采样历史数据低精度70-95%

🏆 最佳实践:数据存储设计检查清单

🔬 深度案例:生产环境实战经验

踩坑与解决方案

在生产环境中,我们经常遇到教科书不会告诉你的问题。以下是常见的实战经验和解决方案:

监控与运维指标

指标告警阈值监控方式
管道延迟超过SLA 120%端到端时间戳追踪
数据量偏差日均偏差超过30%与历史同期对比
错误率超过0.1%错误计数/总记录数
数据新鲜度超过SLA 150%最新数据时间戳
资源利用率CPU持续>80%系统监控
⚠️ 常见反模式
💡 架构演进建议:不要一开始就追求完美架构。从MVP开始,随业务增长逐步演进。每次演进都要回答三个问题:当前瓶颈是什么?解决它的投入产出比如何?是否为后续扩展留了空间?

📚 延伸阅读与参考

推荐资源

🤔 常见问题与解答

Q1: 如何选择批处理还是流处理?

A: 根据业务延迟要求决定:秒级用流处理、分钟级用微批、小时级用批处理。大部分场景批处理足够,流处理用于实时业务场景(风控、监控、推荐)。

Q2: 数据湖会取代数据仓库吗?

A: 不会完全取代,但边界在模糊。湖仓一体(如Iceberg/Delta Lake)正在融合两者优势。未来趋势是统一存储+多引擎计算。

Q3: 初创公司如何选择数据技术栈?

A: 先用云原生服务(BigQuery/Snowflake + Fivetran + dbt + Looker),验证业务后再考虑自建。过早优化是万恶之源。

Q4: 如何说服业务方投资数据治理?

A: 用钱说话:数据质量问题的直接经济损失(错误决策、合规罚款、重复劳动)远大于治理投入。量化问题是第一步。

性能调优实战技巧

数据工程团队协作模式

角色职责交付物
数据工程师管道开发与维护数据管道、基础设施
数据分析师数据分析与报表SQL查询、BI报表
数据科学家模型与实验ML模型、实验报告
数据产品经理需求与优先级PRD、数据产品规划
数据管家数据质量与治理质量规则、数据字典
💡 职业发展建议:数据工程是一个快速发展的领域。保持学习的关键是:1)理解原理而非仅会工具;2)动手实践而非仅看文档;3)关注社区动态,了解最新趋势;4)建立个人项目,积累实战经验。