1.1 传统 ETL 的困境
在云数据仓库普及之前,数据团队面临一个根本性约束:存储和计算都很昂贵。传统的数据处理范式是 ETL——先在数据进入仓库之前,在单独的 ETL 服务器上完成转换。
传统 ETL 的问题 转换逻辑分散在各种 ETL 工具(Informatica、SSIS)中;SQL 脚本没有版本控制;没有测试框架;文档靠手动维护;数据工程师与分析师之间协作困难;重跑历史数据成本极高。
ELT 的核心转变 先将原始数据 Load 进云仓库,再利用仓库自身的强大计算能力做 Transform。Snowflake、BigQuery、Redshift 让 SQL 转换变得极快且廉价,这使得 ELT 成为现代数据栈的首选范式。
ETL vs ELT 对比
| 维度 | ETL | ELT |
|---|---|---|
| 转换时机 | 加载前(在 ETL 服务器) | 加载后(在数据仓库内) |
| 工具 | Informatica, SSIS, Talend | dbt, SQL, Python |
| 原始数据保留 | 通常丢弃 | 保留全部原始数据 |
| 版本控制 | 困难(专有格式) | 容易(纯文本 SQL/Git) |
| 扩展性 | 依赖 ETL 服务器性能 | 随仓库线性扩展 |
| 适用场景 | 敏感数据加密/脱敏、遗留系统 | 现代云数据仓库、大规模分析 |
1.2 分析工程师的诞生
ELT 范式的崛起,催生了一个新职位:分析工程师(Analytics Engineer)。这个角色介于数据工程师和数据分析师之间,专注于在数据仓库内构建可信、可复用的数据模型。
分析工程师的职责定位 数据工程师构建数据管道(Ingestion);分析工程师构建转换层(Transformation),将原始数据变成干净的、文档完善的、经过测试的数据集;数据分析师和业务人员在此基础上做分析和可视化。dbt 正是为分析工程师量身定制的工具。
1.3 dbt 解决了什么问题
dbt 的核心理念是:将软件工程的最佳实践带入数据转换领域。在 dbt 出现之前,数据仓库的转换层往往是混乱的——没有人真正知道一张 BI 报表的数据从哪来、经过了什么逻辑。
- 版本控制:转换逻辑是纯 SQL 文件,Git 天然管理
- 模块化:
ref()函数让模型之间可以互相引用,像函数调用一样组合 - 可测试:内置测试框架,一行 YAML 声明数据质量断言
- 文档化:描述字段自动生成文档站,血缘图自动推断
- 可复现:任意环境(开发/测试/生产)用同一份代码,结果一致
- 可调度:与 Airflow、dbt Cloud 等调度工具无缝集成
1.4 dbt Core vs dbt Cloud
| 特性 | dbt Core(开源) | dbt Cloud(托管) |
|---|---|---|
| 价格 | 免费,开源 | 免费层 + 付费版($50+/用户/月) |
| 运行方式 | 本地 CLI 命令 | 浏览器 IDE + 云端执行 |
| 调度 | 需自建(Airflow/Cron) | 内置任务调度器 |
| CI/CD | 需自建 GitHub Actions | 内置 Slim CI |
| 文档托管 | 需自行部署 | 内置托管 |
| 适用 | 自托管、灵活定制 | 团队协作、快速上手 |
本教程使用 dbt Core 所有示例均基于 dbt Core(命令行),不依赖 dbt Cloud。dbt Core 涵盖了所有核心功能,且完全免费。学会 dbt Core 后,dbt Cloud 只是多了一个 UI 界面。
1.5 安装 dbt
dbt 通过 Python pip 安装。不同的数据仓库需要安装对应的适配器(adapter),每个适配器已包含 dbt Core 本身。
BASH# 推荐:使用虚拟环境隔离
python -m venv dbt-env
source dbt-env/bin/activate # Windows: dbt-env\Scripts\activate
# 安装 dbt + DuckDB 适配器(本地开发,无需云账号)
pip install dbt-core dbt-duckdb
# 安装 dbt + BigQuery 适配器
pip install dbt-core dbt-bigquery
# 安装 dbt + Snowflake 适配器
pip install dbt-core dbt-snowflake
# 安装 dbt + Redshift 适配器
pip install dbt-core dbt-redshift
# 安装 dbt + PostgreSQL 适配器
pip install dbt-core dbt-postgres
# 验证安装
dbt --version
推荐从 DuckDB 开始学习 DuckDB 是一个嵌入式分析数据库,无需安装任何服务,直接在本地文件上运行,完美适合 dbt 学习。本教程前几章均使用 DuckDB 作为演示后端。
1.6 初始化项目:dbt init
一个 dbt 项目就是一个目录,包含模型、测试、宏等文件。用 dbt init 快速生成项目骨架:
BASH# 初始化名为 my_analytics 的项目
dbt init my_analytics
# 交互式选择数据库类型
# Which database would you like to use?
# [1] duckdb [2] bigquery [3] snowflake ...
cd my_analytics
ls -la
项目目录结构如下:
TREEmy_analytics/
├── dbt_project.yml # 项目配置(名称、版本、模型路径等)
├── profiles.yml # 数据库连接配置(通常放在 ~/.dbt/)
├── models/ # SQL 模型文件(核心)
│ └── example/
│ ├── my_first_dbt_model.sql
│ └── schema.yml
├── tests/ # 自定义测试 SQL
├── macros/ # 可复用的 Jinja 宏
├── seeds/ # CSV 文件(直接加载为表)
├── snapshots/ # SCD Type 2 快照
├── analyses/ # 分析用 SQL(不执行为模型)
└── target/ # 编译输出(自动生成,不提交 Git)
1.7 profiles.yml 连接配置
profiles.yml 定义如何连接到数据库。默认路径是 ~/.dbt/profiles.yml(全局共享),也可以放在项目根目录。
YAML# ~/.dbt/profiles.yml
# DuckDB(本地文件,零配置)
my_analytics:
target: dev
outputs:
dev:
type: duckdb
path: ./dev.duckdb # 数据库文件路径
threads: 4
---
# BigQuery(使用服务账号)
my_analytics:
target: dev
outputs:
dev:
type: bigquery
method: service-account
project: my-gcp-project
dataset: dbt_dev
keyfile: /path/to/keyfile.json
threads: 4
timeout_seconds: 300
prod:
type: bigquery
method: service-account
project: my-gcp-project
dataset: dbt_prod
keyfile: /path/to/prod-keyfile.json
threads: 8
BASH# 测试连接是否成功
dbt debug
# 输出示例
# Connection test: [OK connection ok]
1.8 dbt_project.yml 项目配置
dbt_project.yml 是项目的核心配置文件,定义项目名称、模型路径、默认物化方式等:
YAML# dbt_project.yml
name: my_analytics
version: '1.0.0'
config-version: 2
# 指定 profiles.yml 中的 profile 名称
profile: my_analytics
# 文件路径配置
model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]
# 模型默认配置
models:
my_analytics:
# staging 层:轻量视图
staging:
+materialized: view
+schema: staging
# marts 层:持久化表
marts:
+materialized: table
+schema: marts
1.9 名词解释
- ELT Extract-Load-Transform。先提取原始数据并直接加载进数据仓库,再在仓库内部做转换。与 ETL 的区别是转换发生在仓库内,而非独立的 ETL 服务器上。
- 数据仓库 专为分析查询优化的数据库系统,通常是列式存储,支持大规模聚合查询。代表产品:BigQuery、Snowflake、Redshift、DuckDB、ClickHouse。与 OLTP 数据库(MySQL/PostgreSQL)面向事务处理不同,数仓面向分析(OLAP)。
- 分析工程 Analytics Engineering。将软件工程实践(版本控制、测试、文档、模块化)应用于数据转换的新兴领域。分析工程师(Analytics Engineer)是数据工程师和数据分析师之间的桥梁。
- DAG 有向无环图(Directed Acyclic Graph)。在 dbt 中,模型之间的依赖关系形成 DAG。dbt 自动解析 ref() 调用,构建 DAG 并按拓扑顺序执行模型,保证依赖模型先于下游模型运行。
- Adapter(适配器) dbt 与特定数据仓库之间的连接层。每个适配器(如 dbt-bigquery、dbt-snowflake)实现 dbt 标准接口,处理该仓库特有的 SQL 方言和连接方式。
- Materialization(物化) dbt 模型在数据仓库中的持久化方式。view(视图,每次查询时实时计算)、table(全量物理表)、incremental(增量追加/更新)、ephemeral(不物化,作为 CTE 内联)。
- 现代数据栈 Modern Data Stack(MDS)。以云原生工具为核心的数据架构:Fivetran/Airbyte(数据摄取)+ Snowflake/BigQuery(数据仓库)+ dbt(数据转换)+ Looker/Metabase(BI 可视化)。
本章小结
云数据仓库的普及推动了从 ETL 到 ELT 的范式转变,催生了分析工程师职位。dbt 是 ELT 转换层的标准工具,将软件工程的版本控制、测试、文档最佳实践带入数据建模。
dbt Core 免费开源,通过 pip install dbt-core dbt-{adapter} 安装。dbt init 创建项目骨架,profiles.yml 配置数据库连接,dbt debug 验证连接。本教程推荐从 DuckDB 适配器开始学习,零服务器开销,快速上手。