huny.log

기술 포스트 · 데이터 파이프라인·dbt·Airflow

마케팅 데이터 dbt 프로젝트 구조 — staging·marts·metrics·tests 표준

매체별 raw에서 통합 BI 테이블까지 dbt로 묶는 표준 프로젝트 구조. staging/intermediate/marts/metrics 4레이어, 매체 통합 fact 설계, tests·snapshots 운영 표준을 정리합니다.

dbt를 처음 도입한 마케팅 데이터팀이 가장 자주 빠지는 함정은 “구조 없이 모델만 쌓기”예요. 매체별 raw를 그대로 mart로 옮기거나, 한 모델에 다 합치거나. 그러다 모델 300개 넘어가면 누가 무엇을 위해 만들었는지 모르는 카오스가 됩니다. 이 글은 마케팅 데이터를 dbt로 운영하는 표준 4레이어 구조와 각 레이어의 책임을 한 글로 정리합니다. dbt 처음 시작하는 팀, 또는 기존 프로젝트 리팩토링하는 팀에게 옆에 두는 가이드.

dbt 4레이어 구조

dbt 공식 문서와 Modern Data Stack 업계 표준에서 가장 자주 쓰는 4레이어.

레이어책임모델 prefix
Stagingsource raw를 dbt 안으로, 기본 정제stg_
Intermediatestaging 간 join·집계, 비즈니스 룰 시작int_
Marts비즈니스 도메인별 fact·dimensionfct_ / dim_
Metrics의미 있는 KPI semantic layermetric_ 또는 semantic models

마케팅 데이터는 보통 매체가 5-10개, 각 매체에서 4-5개 raw 테이블, 비즈니스 도메인이 3-5개. 모델 100개 넘기는 게 금방이라 레이어가 안 잡혀있으면 빠르게 깨집니다.

dbt 4레이어(staging·intermediate·marts·metrics) 마케팅 데이터 모델링 다이어그램
매체 raw → staging(정제) → intermediate(통합) → marts(비즈니스) → metrics(KPI). 4레이어가 명확하면 모델 300개에도 카오스 안 옴.

Staging 레이어 — source를 dbt 안으로

staging은 raw 원본을 dbt가 다룰 수 있게 정제하는 1단계. 거의 1:1 매핑이지만 다음 정제를 같이 합니다.

  • 컬럼명 표준화 (snake_case, 명확한 이름)
  • 타입 캐스팅 (string → date, micros → numeric)
  • timezone 정규화 (UTC → KST)
  • 환율 변환 전 currency 보존
  • 명백한 dedup (raw에 중복이 있는 경우)
  • 컬럼 이름 prefix로 출처 명시 (meta_campaign_id, google_campaign_id)

매체별 staging:

  • stg_meta__ads_insights — Meta Marketing API insights
  • stg_meta__actions — Meta nested actions array 분해 결과
  • stg_google_ads__ad_group_performance
  • stg_tiktok__ad_report
  • stg_naver_sa__keyword_stats
  • stg_mmp__installs (Appsflyer raw)
  • stg_mmp__events (Appsflyer in-app events)

각 staging은 한 source당 1개. 비즈니스 로직 안 들어가고 그냥 raw 정제만.

Intermediate 레이어 — staging 간 join·통합

intermediate는 staging 간 join이나 통합 비즈니스 룰의 시작 자리. marts에 들어가기 전 중간 단계예요.

예시:

  • int_media_spend_unified — 매체별 staging spend를 한 long format으로
  • int_conversions_attributed — MMP 이벤트 + attribution window 적용
  • int_user_id_resolution — cookie·email·gaid 통합 매핑
  • int_currency_converted — fx_rate 매칭으로 환율 변환

intermediate는 없어도 되지만 staging → marts 사이의 복잡도가 너무 크면 중간 단계가 모델 가독성을 살립니다. 한 비즈니스 룰이 여러 mart에서 재사용되면 intermediate로 빼는 게 표준.

Marts 레이어 — 비즈니스 도메인 fact·dimension

marts는 BI·분석가가 직접 쓰는 자리. 비즈니스 도메인별로 fact·dimension 구분.

마케팅 도메인의 표준 marts:

모델의미
fct_media_spend_daily일자·매체·캠페인 단위 spend·impression·click
fct_conversions사용자·시점·캠페인 attribution이 박힌 conversion
fct_user_journey사용자별 multi-touch 경로
dim_campaign캠페인 메타 (이름·시작·종료·목표)
dim_user사용자 메타 (signup·tier·lifecycle stage)
dim_creative소재 메타 (image·copy·video)
dim_channel채널 정규화 (소문자·표준 이름)

이 7개 모델이 사실상 마케팅 데이터의 BI 토대예요. 회사가 더 깊은 분석이 필요할 때 추가 mart로 확장.

Metrics 레이어 — semantic KPI

metrics는 dbt 1.6+에서 정식 지원되는 semantic layer. KPI 정의를 한 곳에서 관리해서 BI 도구마다 다른 정의가 나오는 문제를 막아요.

dbt semantic model 예시 개념:

  • metric_revenue — 모든 mart에서 revenue 정의가 한 곳
  • metric_roas — spend·revenue 분모분자 규칙
  • metric_cac — acquisition cost 정의
  • metric_ltv — LTV 정의·time window

semantic layer를 도입하면 Looker·Tableau·Metabase 같은 BI 도구가 dbt에서 메트릭을 직접 가져오니까 정의 일관성이 강하게 유지돼요. 회사 사이즈가 큰 단계에서 들이는 게 표준.

Tests — 데이터 품질 게이트

dbt의 강점은 모델마다 test를 박을 수 있는 것. 매주 도는 잡이 깨지면 알림이 와요.

표준 test:

  • unique — primary key 중복 없음
  • not_null — 필수 컬럼 NULL 없음
  • relationships — fk 매칭 (캠페인 ID가 dim_campaign에 있어야)
  • accepted_values — enum 값 (media_source IN (‘meta’, ‘google’, …))
  • custom: spend > 0, conversions >= 0, currency = ‘KRW’

이 5가지를 모든 mart에 박으면 데이터 품질 사고가 사전에 잡혀요. 매주 dbt test가 실패하면 즉시 슬랙 알림이 와야 하는 게 운영 표준.

Macros + 표준 변환

매체마다 timezone·환율·dedup 패턴이 반복되니까 macro로 추상화합니다.

흔히 만드는 macro:

  • convert_to_kst(ts) — UTC timestamp를 KST date로
  • to_krw(amount, currency, date) — fx_rate 매칭으로 KRW 변환
  • dedup_latest(table, key, order_col) — surrogate key dedup
  • unnest_meta_actions(actions_field, action_type, window) — Meta nested array 풀기

dbt-utils 패키지가 많은 표준 macro를 제공하니까 자체 macro는 그 위에 얹는 정도로 충분해요.

Snapshots — 시점별 데이터 보존

마케팅 데이터의 conversion lag·attribution 변경·매체 정책 변경 같은 일이 잦아요. snapshot으로 시점별 데이터를 보존하면 “당시 ROAS”와 “현재 시점 ROAS”를 다 볼 수 있습니다.

대표 snapshot 대상:

  • snapshot_campaign_meta — 캠페인 이름·상태 변경 history
  • snapshot_attribution_rules — 매체 attribution 정책 변경 시점
  • snapshot_dim_user — 사용자 lifecycle stage 변경

snapshot을 매일 도는 잡으로 두면 시점별 비교가 자동으로 가능해요.

운영 안티패턴

  • raw → mart 직행 (staging 없이)
  • 한 모델에 300줄 짜리 CTE 폭주
  • ad-hoc 분석을 mart에 박아두기 (분석은 별도 ad-hoc workspace)
  • test 없는 mart
  • 비즈니스 룰이 BI 쿼리에 흩어짐 (mart에 모아야)
  • 환율·timezone·dedup 룰이 모델마다 다르게

이 6가지를 점검하면 dbt 프로젝트의 건강도가 한눈에 보입니다.

마치며

dbt는 도구가 강해서 처음엔 마구 쓰기 쉽지만, 4레이어 구조가 박혀있어야 100개·300개 모델로 커도 안 깨져요. staging·intermediate·marts·metrics + tests + snapshots, 이 표준만 잡고 시작하면 됩니다.

다음 글로는 Airflow로 dbt run·매체 ingest 오케스트레이션·BigQuery 비용 최적화로 이어집니다.

참고

데이터 파이프라인·dbt·Airflow 카테고리의 다른 글

전체 보기 →