dbt
Data Build Tool
SQL 기반 데이터 변환 도구. ELT의 T(Transform)를 담당. 모듈화와 테스트 지원.
Data Build Tool
SQL 기반 데이터 변환 도구. ELT의 T(Transform)를 담당. 모듈화와 테스트 지원.
dbt(Data Build Tool)는 분석 엔지니어링을 위한 SQL 기반 데이터 변환 프레임워크입니다. ELT(Extract-Load-Transform) 패턴에서 Transform을 담당하며, SELECT 문만 작성하면 테이블/뷰 생성을 자동화합니다. 소프트웨어 엔지니어링의 모범 사례(버전 관리, 테스트, 문서화)를 데이터 변환에 적용합니다.
dbt의 핵심 기능은 ref() 함수를 통한 모델 간 의존성 관리입니다. ref('stg_orders')처럼 다른 모델을 참조하면 dbt가 자동으로 실행 순서(DAG)를 계산하고 스키마를 치환합니다. source() 함수는 원천 데이터에 대한 참조와 freshness 체크를 제공합니다.
Jinja 템플릿과 매크로로 SQL을 프로그래밍 언어처럼 재사용할 수 있으며, dbt test로 데이터 품질(unique, not_null, relationships 등)을 검증합니다. dbt docs generate는 자동 문서화와 데이터 리니지 그래프를 생성합니다.
dbt Cloud는 스케줄링, CI/CD, IDE를 제공하는 SaaS이고, dbt Core는 CLI 오픈소스입니다. Snowflake, BigQuery, Redshift, Databricks 등 주요 데이터 웨어하우스와 연동되며, Analytics Engineering 직군의 표준 도구로 자리잡았습니다.
-- dbt 모델 예제: ref()와 source() 활용
-- ========== models/staging/stg_orders.sql ==========
-- source()로 원천 데이터 참조
{{ config(materialized='view') }}
SELECT
id AS order_id,
user_id AS customer_id,
order_date,
status,
amount AS order_amount,
_loaded_at
FROM {{ source('raw', 'orders') }}
WHERE _loaded_at > CURRENT_DATE - INTERVAL '90 days'
-- ========== models/staging/stg_customers.sql ==========
{{ config(materialized='view') }}
SELECT
id AS customer_id,
name AS customer_name,
email,
created_at AS signup_date,
segment
FROM {{ source('raw', 'customers') }}
-- ========== models/marts/fct_orders.sql ==========
-- ref()로 다른 모델 참조 (의존성 자동 관리)
{{ config(
materialized='incremental',
unique_key='order_id',
on_schema_change='sync_all_columns'
) }}
WITH orders AS (
SELECT * FROM {{ ref('stg_orders') }}
{% if is_incremental() %}
WHERE order_date > (SELECT MAX(order_date) FROM {{ this }})
{% endif %}
),
customers AS (
SELECT * FROM {{ ref('stg_customers') }}
)
SELECT
o.order_id,
o.customer_id,
c.customer_name,
c.segment AS customer_segment,
o.order_date,
o.status,
o.order_amount,
CURRENT_TIMESTAMP AS _updated_at
FROM orders o
LEFT JOIN customers c ON o.customer_id = c.customer_id
시니어: "이 집계 로직을 dbt 모델로 만들어서 ref()로 참조하면 재사용할 수 있어요. 지금 같은 로직이 5군데 복붙되어 있는데, 한 곳에서 바꾸면 다 반영되게요."
주니어: "incremental 모델로 만들면 전체 재처리 안 해도 되나요?"
시니어: "네, is_incremental() 조건으로 신규 데이터만 처리해요."
면접관: "dbt에서 ref()와 source()의 차이점은 무엇인가요?"
지원자: "source()는 원천 데이터(raw layer)를 참조하고 freshness 체크가 가능합니다. ref()는 다른 dbt 모델을 참조하며 의존성 그래프(DAG)를 자동으로 구성합니다."
시니어: "이 모델에 테스트가 없네요. 최소한 PK에 unique, not_null 테스트랑, FK에 relationships 테스트는 추가해주세요."
주니어: "schema.yml에 tests 섹션 추가하겠습니다."