최근 시작한 미니프로젝트에서 파이프라인을 만들다보니 ETL보다 ELT가 효율적일 거 같아서 구상을 하던중 DBT라는 것을 알게 되었다.
그래서 이번 기회에서 DBT에 대해 배우게되었다.
dbt(Data Build Tool)를 처음 접했을 때, 처음 든 생각은 단순했다.
“SQL로 테이블 만드는 건데, 이걸 왜 굳이 도구로 써야 하지?”
온라인에서 대략 찾아봤지만 구체적인 기술과 사례를 보며 SQL과 비교해야 이해가 될 거 같아서 인프런 미쿡엔지니어 강사님의 강의를 결제하여 듣게 되었다.
처음은 dbt를 배우기 전, 기존 ETL → ELT 변화를 알려주셨는데 왜 과거엔 ETL을 쓸 수밖에 없었고 현재에선 ELT를 사용하는지 ELT로 바뀌면서 DBT가 왜 중요해지게 되었는지 알게 되었다.
간략하게 정리하면 과거엔 데이터 저장을 온프레미스로 저장을했는데 비용이 비싸다보니 적재하기 전에 데이터 가공이 필요하였다. -> ETL
현대에서는 데이터웨어하우스가 커지고 비용도 저렴해지고 분석이 중요해지면서 적재 후 가공하는 방식으로 바뀌었다. 이때 가공처리할 때 효과적인 도구가 dbt이다현대의 ETL/ELT 쓰임
현대 ETL이 강한 영역
- 실시간 스트리밍
- 대용량 전처리
- 로그 파싱, 복잡한 비정형 처리
현대 ELT + dbt가 강한 영역- 분석용 데이터 모델링
- BI/리포트용 테이블
- 비즈니스 로직 정제
- 컬럼 표준화, 조인, 집계
즉, 실무에서는 요즘 이런 분업이 자연스럽다.
수집/적재 → Airflow, Fivetran, Kafka
변환/모델링 → dbt
처음 강의를 따라 DBT RUN을 했을 때 어떤 파일을 참고해서 어떻게 처리되는지 이해가 되지 않았다.
그래서 잠시 강의를 멈춰두고 폴더 구조 및 참조 파일을 찾아가며 공부를 하였다.
아직도 뒤돌아서면 뭘 어떻게 실행해야되는지는 헷갈리지만 파일 참조가 문제 있으면 어떤 파일을 참고해야하는지 알 수 있게 되었다.
DBT는 자체적으로 약속된 디렉토리 포맷이 있는데 맞춰서 넣어줘야 dbt run을 했을 때 파일이 잡힌다
models/ → 실행되는 변환 모델
analyses/ → 실행되지 않는 분석용 SQL
seeds/ → CSV → 테이블
tests/ → 테스트
macros/ → Jinja 함수
snapshots/ → 변경 이력 관리
같은 SQL 파일이라도 어느 디렉토리에 있느냐에 따라 dbt의 취급이 완전히 달라진다.
ex)
models/에 있으면 → dbt run 대상
analyses/에 있으면 → 참고용 SQL (실행 안 됨)
또 dbt run을 실행했을 때 동일한 포맷인데 파일이 잡히는 것과 안잡히는 것이 있었다. 찾아보니 위 최상단 블록에 source와 model이 달랐다.
source란?
이미 웨어하우스에 존재하는 원본 테이블을 참조하는 역할
- dbt가 만들지 않음
- dbt는 오직 “존재를 선언”만 한다
- {{ source('dvdrental', 'rental') }}
→ “이 테이블은 이미 있고, 난 읽기만 할 거다”
model.yml이란?
model.sql파일을 설명하는 파일
- 테이블 및 컬럼 설명
- 컬럼 규칙 검사
- 문서화 사용
model.sql이란?
dbt가 SQL을 실행해서 만들어내는 로직파일
- 테이블 또는 뷰
- 가공, 조인, 집계의 주체
-- models/stg_rental.sql
select
rental_id,
rented_at as rental_date
from {{ source('dvdrental', 'rental') }}
“어차피 컬럼 바뀌면 SQL 다 고쳐야 하는 거 아닌가?”
는 생각을 하였고 무엇이 sql과 다른지 찾고 이해해보려했다
(강의 일부 자료 요약하여 정리)
1️⃣ 변경 감지
원본 컬럼 삭제/변경 시 테스트 실패
예상치 못한 변경을 조기에 인지
-> 추후에 강의를 더 들어봐야 알 수 있을 거 같다..
2️⃣ 변경 격리
컬럼 변경을 staging 모델 한 곳에서만 흡수
만약 데이터 웨어하우스에서 컬럼명을 변경하면 아래 연결된 파일들도 싹다 바꿔줘야 된다 생각했는데 staging 파일에서 바뀐 컬럼명에 기존 컬럼명을 별칭해서 참조할 수 있어 한번만 바꿀 수 있는 게 장점이었다
ex)
# 데이터 웨어하우스 컬럼명이 아래와 같이 변경되었다고 하자
# post_date -> post_at
# 그럼 아래 연결된 파일을 다 바꾸는 것이 아닌 staging 파일에서 아래와 같이 처리하면 된다
select
post_at as post_date
from {{source('insta','insta_post'}}
3️⃣ 영향 범위 추적
lineage로 어떤 모델이 영향을 받는지 즉시 확인 가능
내가 실제로 헷갈려서 질문했던 부분 정리
그 외에도 공부하면서 궁금했던 지점들을 정리해보았다:
schema.yml도 yml인데 왜 source로 안 잡히지?
→ 최상위 블록이 models이기 때문 (메타데이터용)
analyses에 SQL 두면 왜 실행 안 되지?
→ 디렉토리 자체가 실행 대상 아님
source에 컬럼 적으면 자동으로 SQL 파일 생기나?
→ 아니다. source는 선언, SQL은 사람이 작성
model에서도 DDL 써도 되나?
→ 안 쓰는 게 원칙. dbt가 생성 담당
왜 staging 모델이 필요하지?
→ 원본 변화 흡수 + downstream 보호
이 질문들을 하나씩 정리하면서
dbt는 “자동화 도구”가 아니라 “설계 규칙을 강제하는 도구”라는 걸 이해하게 됐다.
마무리하며
아직도 이해안가는게 많지만 이해시키며 정리해보겠다