
ETL중에서 T(transform)에 최적화된 도구인 dbt에서 기초가 되는 Materializations, Seeds 그리고 Sources에 대해서 정리해봤습니다.
materialization은 데이터 모델을 정의할 때 이 모델이 데이터베이스에서 어떻게 저장되고 관리될지를 결정하는 방식입니다. dbt는 기본적으로 여러 가지 materialization 전략을 제공하여, 사용자가 필요에 따라 모델을 효율적으로 관리할 수 있도록 돕습니다. 주요 materialization 전략은 다음과 같습니다
데이터가 자주 변경되지 않고, 정기적으로 참조를 하는경우 적합한 형태입니다. 예를 들어 매일밤 "전체 데이터"를 업데이트 하는 배치작업의 경우 적합하다고 볼 수 있습니다.
흔히 우리가 물리적으로 저장하는 형태라고 보시면됩니다.
장점으로는, 물리적으로 저장되기 때문에 조회속도가 빠르며, 변경되지 않는 데이터에 대해서 매번(쿼리시)계산 할 필요가 없기때문에 효율적입니다.
단점으로는, 저장공간을 차지하기 때문에 대교모 데이터를 자주 재생성을 하게 되면 저장소 관리가 필요하게 됩니다.
이것 역시 우리가 데이터를 저장하는 방식중에서 "뷰"라고 부르는 그것이 맞습니다. 빠르게 변경되는 데이터가 있을때 최신데이터를 항상 조회해야하는 경우 사용하기 적합한 형태입니다.
장점으로는, 저장공간을 차지하지 않기때문에 가볍게 작업할 수 있고, 데이터가 실시간 업데이트 되기때문에 항상 최신의 정보로 조회가 됩니다.
단점으로는, 매 쿼리시 마다 연산이 되기때문에 데이터가 많을수록 속도가 느려지게 됩니다.
일시적으로만 사용되는 가상의 데이터 모델이라고 하는 Ephemeral은 view와 잘 구분하셔야할것같습니다.
장점으로는,
1. 간결한 코드작성: Ephemeral 모델은 다른 모델에서 쉽게 참조할 수 있는 쿼리를 제공합니다. 이는 코드의 복잡성을 줄이고, 재사용성을 높입니다. 특히 짧은 쿼리나 필터링 된 데이터를 사용할 때 유용합니다.
2. 쿼리 구조의 유연성 : Ephemeral모델을 사용하면 여러 모델에서 다양한 방식으로 같은 쿼리를 변형해서 사용할 수 있습니다.
3. 간단한 데이터 흐름 : 데이터 파이프라인을 만들때 복잡한 데이터 변환을 수월하게 만들어주며, 다른모델에 삽입할때 기존쿼리의 일부분처럼 쉽게사용할 수 있다.
4. 임시데이터처리 : Ephemeral모델은 일시적으로 필요한 데이터나 중간결과를 처리할 때 유용합니다. 특정 데이터 조작이나 변환 과정에서 중간결과를 유지할 필요가 없을때 사용하면 효과적입니다.
(DB에 저장되지 않아서 중간결과만 임시로 쿼리내부에서 사용하기 때문에 성능이 높습니다.)
5. 디버깅과 테스트 용이성 : 작은데이터셋에 대해 Ephemeral 모델을 사용하는 것이 효과적일 수 있습니다. 이 경우, 중복 실행의 영향을 덜 받으며, 성능 저하가 크지않기 때문에 유용할수잇습니다.
->
개인적으로 "비즈니스 로직"을 태울때 이러한것들을 모듈화해서 독립적으로 작성하면 효율적이라는 생각이 드네요, 예를들어 고객의 segment를 나눈다던가, 할인율 계산, VAT계산등,
그리고 간단하게 단위 테스트 수행을 하는데 있어서도, 효율적으로 진행할 수 있을것이라는 생각이드네요
단점으로는, 다른 쿼리에서 재상용이 불가능 합니다. 만약 여러 모델이 동일한 Ephemeral모델을 참조하게 되면, dbt는 이 Ephemeral 쿼리를 각 모델의 쿼리내에 각각 삽입합니다. 결과적으로, 동일한 Ephemeral쿼리가 여러 번 중복되어 실행될 수 있습니다. 이 경우 성능에 영향을 미칠 수 있습니다.
view VS Ephemeral
1. view의 경우 데이터가 자주변경되지 않거나, 주기적으로 업데이트 되는 경우에 유용합니다. -> DB에 정의되며, 반복호출시 쿼리 최적화가 가능하기때문에
2. 동일한 쿼리를 여러 모델에서 사용하는 경우 view를 사용하면 좋다. -> "캐싱"
3. 복잡한 데이터 변환로직이 있을때 view를 사용하면 그 결과를 쉽게 재사용할수있으며 관리하기 용이하다. -> 복잡한 로직이 view테이블에서 정의되어있으면 이것을 참조하는 다른모델에 모두 한번에 반영되기 때문이다.
4. Ephemeral의 경우특정 데이터 변환이나 필터링을 위해 임시로 필요한 데이터를 처리할때 유용하다. 예를 들어, 특정 분석을 위해 한 번만 사용되는 쿼리의 경우 적합하다!!
5. 복잡한 쿼리 구조를 단순화 하고자 할때, Ephemeral 모델로 간단한 쿼리를 모듈화하여 관리하기에 적합하다.
6. 비즈니스 로직이 자주 변경되는 경우, Ephemeral모델을 사용하면 변경사항을 쉽게 반영할 수 있다.
데이터의일부만 업데이트하여 새로운 데이터를 추가하는 방식입니다. 이 방법은 대량의 데이터가 있을때 성능을 최적화 할 수 있으며, 전체 데이터셋을 매번 재생성할 필요가 없습니다. 일반적으로 최신 데이터만을 처리하는데 적합한 방법입니다.
단점으로는, 테이블을 관리하는 추가로직이 필요합니다. 예를들어 "변경사항 추적", "중복 방지(키값 설정)", "SCD TYPE2관리" 등이 있을것 같네요.
그리고, 누적된 데이터에 대한 오류처리에도 신경을 써야합니다.
시간이 지남에 따라 누적된 데이터가 의도치 않게 중복되거나 불일치 발생이 될경우 어떻게 처리할지 신경써야하며, 잘못된 데이터 삭제 및 보정을 감지하는 로직이 있어야합니다. 즉, 데이터 품질을 검증할 코드가 필요하게됩니다!!
Materialization의 경우 용도에 맞게 적합한 방식을 다루는것이 중요해 보입니다.
seed는 dbt프로젝트에 포함된 csv파일을 데이터베이스 테이블로 로드하여 사용할 수 있게해주는 기능입니다. 주로 외부 시스템에 연결하지 않고도 테스트, 초기 데이터 설정 또는 참조 테이블을 쉽게 설정하기 위해 사용됩니다.
-> 비즈니스 적으로 참조해야하는 테이블이 있다면 Csv형태로 가져와서 참조할 수 있게 하면 좋을것같네용
사용방법은 seed/ 폴더에 csv파일을 저장하고 "dbt seed"명령어를 사용하여 테이블로 로드 할 수 있습니다.
dbt에서 source는 데이터 소스, 즉 원시 데이터가 저장된 장소를 정의하는 개념입니다. dbt의 소스 기능을 사용하면 데이터베이스에 있는 기존 테이블이나 뷰를 dbt 프로젝트 내에서 쉽게 참조할 수 있습니다. 소스는 원시 데이터를 다루는 여러 작업을 수행하는 데 유용하며, dbt의 데이터 모델링에서 중요한 역할을 합니다.
# models/sources.yml
version: 2 # dbt 소스 정의의 버전
sources:
- name: sales # 소스 이름
database: my_database # 데이터베이스 이름
schema: raw # 스키마 이름
tables:
- name: o # 테이블 별칭
identifier : orders # 테이블 이름
description: "Contains all customer orders." # 테이블 설명
columns: # 열 정의
- name: order_id
description: "Unique identifier for each order."
- name: customer_id
description: "Identifier for the customer who made the order."
- name: airbnb
schema: raw
tables:
- name: listings
identifier: raw_listings
이렇게 정의를 해두면 모델에서 아래와같이 참조하여 사용할 수 있습니다.
-- models/orders_analysis.sql
with raw_orders as (
select * from {{ source('sales', 'orders') }}
)
select
customer_id,
count(order_id) as total_orders,
sum(order_amount) as total_spent
from raw_orders
group by customer_id;
요약
- dbt source는 원본 데이터를 정의하고, 그 데이터를 dbt모델에서 쉽게 사용할 수 있도록 도와줍니다.
- 데이터의 출처를 명확히 하고, 팀원들이 데이터를 이해하는 데 도움을 줍니다.
- 소스를 통해 원본 데이터를 참조하면, 복잡한 쿼리를 작성하지 않고도 필요한 데이터를 쉽게 가져올 수 있습니다.
- 이렇게 dbt source를 활용하면 데이터 파이프라인을 더욱 명확하고 효율적으로 관리할 수 있습니다.