📊데이터공학

dbt

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 섹션 추가하겠습니다."

주의사항

더 배우기