跳到主要内容

dbt

问题

什么是 dbt?它如何改变数据转换的工作方式?

答案

什么是 dbt

dbt(data build tool)是现代数据栈中的数据转换工具,核心理念:用 SQL + Jinja 模板在数仓内做转换,把分析工程变成软件工程。

dbt 核心功能

功能说明
SQL 模型每个 .sql 文件就是一个模型(表/视图)
ref 引用模型间通过 ref() 引用,自动生成依赖
Jinja 模板支持变量、循环、条件,SQL 复用
数据测试内置 not_nulluniqueaccepted_values 测试
文档自动生成数据字典和血缘图
增量更新incremental 物化方式,只处理新数据

模型示例

models/staging/stg_orders.sql
-- 配置模型
{{ config(materialized='view') }}

-- 从 ODS 层清洗
SELECT
id AS order_id,
user_id,
CAST(created_at AS DATE) AS order_date,
CASE status
WHEN 1 THEN 'pending'
WHEN 2 THEN 'paid'
WHEN 3 THEN 'shipped'
WHEN 4 THEN 'completed'
ELSE 'unknown'
END AS status,
amount
FROM {{ source('raw', 'orders') }}
WHERE amount > 0
models/marts/fct_daily_revenue.sql
{{ config(materialized='table') }}

SELECT
order_date,
COUNT(DISTINCT order_id) AS order_count,
SUM(amount) AS total_revenue,
COUNT(DISTINCT user_id) AS buyer_count
FROM {{ ref('stg_orders') }}
WHERE status = 'completed'
GROUP BY order_date

dbt 测试

models/staging/schema.yml
version: 2

models:
- name: stg_orders
columns:
- name: order_id
tests:
- not_null
- unique
- name: status
tests:
- accepted_values:
values: ['pending', 'paid', 'shipped', 'completed', 'unknown']
- name: amount
tests:
- not_null

dbt 项目结构

dbt_project/
├── dbt_project.yml # 项目配置
├── models/
│ ├── staging/ # 贴源层(view)
│ │ ├── stg_orders.sql
│ │ └── schema.yml
│ ├── intermediate/ # 中间层
│ │ └── int_order_items.sql
│ └── marts/ # 集市层(table)
│ ├── fct_daily_revenue.sql
│ └── dim_users.sql
├── tests/ # 自定义测试
├── macros/ # 可复用 SQL 宏
└── seeds/ # 静态 CSV 数据

常见面试问题

Q1: dbt 和 Spark SQL 有什么区别?

答案

对比dbtSpark SQL
定位转换编排工具计算引擎
执行生成 SQL 推给数仓执行自己执行计算
适用云数仓(Snowflake/BQ)Hadoop 生态
工程化✅ 测试、文档、版本控制需要自己实现

Q2: dbt 的 materialized 有哪些选项?

答案

  • view:创建视图,每次查询实时计算
  • table:创建物理表,dbt run 时全量刷新
  • incremental:增量更新,只处理新数据
  • ephemeral:不创建物理对象,内联为 CTE

Q3: dbt 怎么做增量更新?

答案

{{ config(materialized='incremental') }}

SELECT * FROM {{ ref('stg_events') }}

{% if is_incremental() %}
-- 只处理上次运行之后的新数据
WHERE event_time > (SELECT MAX(event_time) FROM {{ this }})
{% endif %}

相关链接