3. 数据仓库与数据湖:概念辨析、适用场景、ETL与ELT流程简介

聊到数据存储架构,有两个词你一定绕不开:数据仓库和数据湖。

很多刚入行的朋友容易把它们搞混,甚至觉得“不就是存数据的地方吗?”

嗯,还真不是一回事。我刚开始做数据工程那会儿,也踩过这个坑。当时项目急着上线,我们一股脑把所有数据都往一个“仓库”里灌,结果报表跑不出来,业务方天天催。后来才明白,选错存储架构,后面全是坑。

3.1 数据仓库:为分析而生的“精装房”

数据仓库(Data Warehouse,简称 DW 或 DWH),说白了就是专门用来做分析和报表的数据库。

它和我们平时用的 MySQL、PostgreSQL 这类 OLTP 数据库不一样。OLTP 数据库是给“人”用的,处理订单、用户登录这种高频小事务。而数据仓库是给“分析”用的,处理海量历史数据的聚合查询。

核心特征:

  • 面向主题:按业务主题组织数据,比如“销售”、“库存”、“用户”。
  • 集成性:数据来自多个源,经过清洗、去重、统一编码。
  • 非易失性:数据一旦写入,通常不会修改,只做批量追加。
  • 随时间变化:保存历史快照,支持趋势分析。

我个人的习惯是,把数据仓库想象成精装房。开发商(数据团队)已经把水电、墙面、地板都装好了,你拎包入住就行。数据仓库里的数据是结构化的,Schema 是预先定义好的(Schema-on-Write)。

举个例子,你查“2024年Q3华东区手机品类销售额”,数据仓库能在几秒内给你结果。因为它已经提前把数据清洗、建模、聚合好了。

3.2 数据湖:保留原始状态的“毛坯房”

数据湖(Data Lake)的概念就完全不一样了。

它存储的是原始格式的数据,可以是结构化的 CSV、半结构化的 JSON、非结构化的图片、音频、日志文件。数据进来的时候,不做任何转换,原封不动地存着。

这就像毛坯房。开发商只给你一个水泥框架,水电怎么走、墙刷什么颜色,你自己看着办。数据湖的 Schema 是在读取时才定义的(Schema-on-Read)。

我曾经在一个 IoT 项目里用过数据湖。传感器每秒上报温度、湿度、震动数据,一天几个 TB。如果用传统数据仓库,光建模就得累死。但数据湖直接往里扔,等需要分析“设备故障预测”时,再按需读取、处理。

我的建议:

如果你不确定数据将来怎么用,或者数据格式经常变,优先考虑数据湖。它给你最大的灵活性,但代价是——你得自己管好“数据沼泽”的问题,别让数据变成没人理的垃圾堆。

3.3 核心对比:一张表说清楚

对比维度 数据仓库 数据湖
数据形态 结构化,已清洗 原始,任意格式
Schema 定义 写入时定义(Schema-on-Write) 读取时定义(Schema-on-Read)
主要用户 业务分析师、报表用户 数据科学家、数据工程师
典型场景 固定报表、KPI 看板 机器学习、探索性分析
存储成本 较高(需要预处理和索引) 较低(廉价对象存储)
数据质量 高,经过治理 低,需要自行清洗
典型技术 Snowflake, Redshift, BigQuery S3, ADLS, Delta Lake

你想想看,如果业务方每天都要看固定的日报、月报,数据仓库是首选。但如果数据科学家要训练一个推荐模型,需要原始点击流日志,那数据湖更合适。

3.4 ETL 与 ELT:流程的两种哲学

聊完存储,咱们得说说数据怎么进去的。这就引出了两个经典流程:ETL 和 ELT。

3.4.1 ETL:先转换,再加载

ETL 是传统数据仓库时代的标配。流程是:

  1. Extract(抽取):从源系统(MySQL、API、日志文件)拉数据。
  2. Transform(转换):在中间服务器(通常是 ETL 工具)上做清洗、聚合、脱敏。
  3. Load(加载):把处理好的数据写入目标数据仓库。

这样做的好处是,数据仓库里存的是“干净”的数据,查询效率高。但坏处也很明显——如果源数据格式变了,ETL 脚本得跟着改,维护成本高。

我记得有一次,上游业务系统把订单状态字段从数字改成了英文缩写,我们的 ETL 脚本直接崩了,报表停了半天。从那以后,我养成了一个习惯:ETL 脚本里一定要加 Schema 校验和异常告警。

3.4.2 ELT:先加载,再转换

ELT 是随着数据湖和云数仓兴起而流行起来的。流程是:

  1. Extract(抽取):从源系统拉数据。
  2. Load(加载):直接把原始数据丢进数据湖或云数仓。
  3. Transform(转换):在目标系统内部(比如用 SQL 或 Spark)进行转换。

说白了,就是把转换的负担从 ETL 服务器转移到了计算引擎上。现在云数仓(比如 Snowflake、BigQuery)的计算能力很强,ELT 越来越常见。

避坑指南:

我曾经在一个项目里盲目跟风用 ELT,结果数据量太大,每次转换都要跑几个小时,成本飙升。后来发现,ELT 适合计算资源弹性、数据量大的场景;如果数据量小、对延迟敏感,传统 ETL 反而更靠谱。别为了“新”而“新”。

3.5 一张图看懂整体流程

下面这张 SVG 图,把数据仓库、数据湖、ETL、ELT 的关系串起来了。你可以把它当作本章的知识地图。

数据仓库与数据湖流程对比图 数据仓库 vs 数据湖:ETL / ELT 流程对比 数据源(Data Sources) 业务数据库 日志文件 API 接口 IoT 设备 其他 ETL 路径(传统数据仓库) Extract Transform Load ELT 路径(数据湖 / 云数仓) Extract Load Transform 目标:数据仓库 结构化、已清洗、Schema-on-Write 典型:Snowflake, Redshift, BigQuery 目标:数据湖 原始格式、Schema-on-Read 典型:S3, ADLS, Delta Lake 数据消费层 BI 报表 Ad-hoc 查询 机器学习 数据产品 数据目录 / 元数据管理

3.6 怎么选?我的经验法则

没有银弹。选数据仓库还是数据湖,用 ETL 还是 ELT,取决于你的业务场景、团队能力和技术栈。

  • 业务方要固定报表,数据质量要求高 → 数据仓库 + ETL。别折腾,稳定第一。
  • 数据科学家要探索原始数据,格式多变 → 数据湖 + ELT。给足灵活性。
  • 两者都要? → 可以考虑“湖仓一体”(Lakehouse),比如 Databricks 的 Delta Lake 或 Apache Iceberg。它试图结合数据湖的灵活性和数据仓库的可靠性。我最近两个项目都在用,效果还不错。

一个小技巧:

不管选哪种架构,元数据管理一定要跟上。没有元数据的数据湖就是数据沼泽。我习惯在数据入湖的第一时间,自动采集 Schema、行数、更新时间等元信息,写入数据目录。这样后面找数据、做血缘分析都方便很多。