7분

데이터 모델링 선택이 아키텍처를 장기적으로 고정하는 방법

데이터 모델링 결정은 수년간 데이터 스택을 규정합니다. 락인이 발생하는 지점, 트레이드오프, 그리고 선택지를 유지하는 실용적 방법을 확인하세요.

데이터 모델링 선택이 아키텍처를 장기적으로 고정하는 방법

왜 데이터 모델이 장기 락인을 만든는가

데이터 아키텍처에서의 “락인”은 단지 공급업체나 도구의 문제가 아닙니다. 스키마를 변경하는 것이 너무 위험하거나 비용이 많이 들어서 하지 않게 될 때 발생합니다—그 이유는 대시보드, 리포트, ML 기능, 통합, 그리고 데이터가 "무엇을 의미하는지"에 대한 공유된 이해가 깨지기 때문입니다.

데이터 모델은 다른 모든 것보다 오래 살아남는 결정 중 하나입니다. 웨어하우스는 교체되고, ETL 도구는 바뀌며, 팀은 재구성되고, 네이밍 규칙은 흐려집니다. 하지만 수십 개의 다운스트림 소비자가 테이블의 컬럼, 키, 그리고 그레인에 의존하게 되면 모델은 계약이 됩니다. 이를 변경하는 것은 단순한 기술적 마이그레이션이 아니라 사람과 프로세스 전반의 조정 문제입니다.

왜 모델링 선택은 도구보다 오래가는가

도구는 교체 가능하지만, 종속성은 그렇지 않습니다. 한 모델에서 “revenue”로 정의된 지표가 다른 모델에서는 “gross”일 수 있습니다. 고객 키가 한 시스템에서는 "청구 계정(billing account)"을 의미하고 다른 시스템에서는 "사람(person)"을 의미할 수 있습니다. 그런 의미 수준의 약속은 퍼진 뒤 되돌리기 어렵습니다.

장기 락인의 주요 결정 지점

대부분의 장기 락인은 초기의 몇 가지 선택으로부터 비롯됩니다:

  • 그레인(Grain): 한 행이 무엇을 나타내는가(이벤트당, 일별, 고객당, 주문 품목당 등)
  • 키와 정체성: 사물을 어떻게 고유하게 식별하는가, 그리고 그 정체성이 변경될 수 있는가
  • 히스토리: 변경을 시간에 따라 저장할 것인지, 방법은(스냅샷, SCD, 이벤트 로그)
  • 의미(세맨틱): 비즈니스 정의가 어디에 위치하는가(메트릭, 디멘션, 공유 로직)
  • 접근 패턴: 분석가, BI 도구, 애플리케이션, ML 중 무엇에 최적화하는가

트레이드오프는 정상입니다. 목표는 약속을 피하는 것이 아니라 가장 중요한 약속을 의도적으로 하고, 가능한 한 많은 것들을 되돌릴 수 있게 유지하는 것입니다. 이후 섹션은 변경이 불가피할 때 파손을 줄이는 실용적 방법에 집중합니다.

데이터 모델이 닿는 것들(생각보다 더 넓다)

데이터 모델은 단순한 테이블 집합이 아닙니다. 초판이 끝나기도 전에 많은 시스템이 조용히 그 모델에 의존하는 계약이 됩니다.

명백한 종속성들

한 번 모델이 “공식화”되면 다음으로 확산되는 경향이 있습니다:

  • 대시보드와 리포트(저장된 쿼리, 차트 로직, 필터)
  • ML 피처(피처 스토어, 학습 파이프라인, 온라인 스코어링 입력)
  • 리버스 ETL(“고객 상태”나 “이탈 위험”을 CRM으로 동기화)
  • 내부 또는 파트너 API(웨어하우스를 직접 읽는 서비스)
  • 데이터 공유(공유, Delta sharing, 벤더로의 익스포트)

각 종속성은 변경 비용을 곱합니다: 더 이상 하나의 스키마만 편집하는 것이 아니라 많은 소비자를 조정해야 합니다.

한 메트릭이 여러 복사본이 되는 방법

하나의 공개된 메트릭(예: “활성 고객”)은 중앙화되어 있지 않은 경우가 많습니다. 누군가는 BI 도구에서 정의하고, 다른 팀은 dbt에서 재구현하고, 성장 분석가는 노트북에 하드코딩하며, 제품 대시보드에서는 약간 다른 필터로 다시 삽입합니다.

몇 달 후에는 “한 메트릭”이 사실상 경계 케이스 규칙이 다른 여러 유사 메트릭이 됩니다. 지금 모델을 바꾸면 쿼리가 깨지는 것뿐 아니라 신뢰가 깨질 위험이 큽니다.

ER 다이어그램에 보이지 않는 숨은 결합

락인은 다음과 같은 곳에 숨어 있습니다:

  • 다운스트림 도구가 가정하는 명명 규칙(예: *_id, created_at)
  • 사람들이 정식 경로로 간주하는 조인 경로(“orders는 항상 X로 customers와 조인된다”)
  • 컬럼에 베어 있는 암묵적 비즈니스 규칙(예: 환불 제외, 타임존 로직)

운영적 영향: 비용, 지연, 사고 대응

모델의 모양은 일상 운영에 영향을 줍니다: 넓은 테이블은 스캔 비용을 올리고, 높은 그레인의 이벤트 모델은 지연을 증가시키며, 불분명한 라인리지는 사고 원인 규명(티어) 난도를 높입니다. 메트릭이 드리프트하거나 파이프라인이 실패하면, 온콜 대응은 모델이 얼마나 이해 가능하고 테스트 가능한지에 달려 있습니다.

그레인 결정: 첫 아키텍처 약속

“그레인”은 테이블이 나타내는 상세 수준입니다—한 행이 정확히 무엇인가. 작은 것 같지만 이것이 종종 아키텍처를 조용히 고정하는 첫 번째 결정입니다.

그레인, 간단한 예시

  • Orders 그레인: 한 행이 주문 하나(order_id). 주문 합계, 상태, 고수준 리포팅에 적합합니다.
  • Order items 그레인: 한 행이 주문의 품목 하나(order_id + product_id + line_number). 제품 구성, 품목별 할인, SKU별 반품에 필요합니다.
  • Sessions 그레인: 한 행이 사용자 세션 하나(session_id). 퍼널 분석과 어트리뷰션에 유용합니다.

문제는 비즈니스가 필연적으로 물어볼 질문을 자연스럽게 답할 수 없는 그레인을 선택할 때 시작됩니다.

잘못된 그레인이 어색한 데이터를 만드는 방법(및 추가 테이블)

만약 오직 orders만 저장하고 나중에 “수익 기준 상위 제품”이 필요해지면 다음과 같은 일을 해야 합니다:

  • 주문 행에 품목의 배열/JSON을 억지로 집어넣는다(쿼리하기 어려움), 또는
  • 나중에 order_items 테이블을 만들고 백필한다(마이그레이션 고통), 또는
  • 중복 로직을 가진 여러 파생 테이블을 만든다(orders_by_product, orders_with_items_flat)—시간이 지나며 이들은 서로 달라집니다.

마찬가지로 sessions를 주된 팩트 그레인으로 선택하면 구매를 세션에 신중히 연결하지 않는 한 “일별 순수 수익(net revenue by day)”은 어색해집니다. 깨지기 쉬운 조인, 중복 집계 위험, 그리고 “특별한” 메트릭 정의가 생깁니다.

미래 조인을 결정하는 관계들

그레인은 관계와 밀접히 연결됩니다:

  • 일대다(One-to-many)(order → items): “하나” 쪽으로 모델링하면 세부가 사라지거나 반복 컬럼이 생깁니다.
  • 다대다(Many-to-many)(sessions ↔ campaigns, products ↔ categories): 브리지 테이블이 필요합니다. 초기에는 이를 건너뛰면 나중에 ETL에 비즈니스 의미를 하드코딩하는 해결책이 생기는 경향이 있습니다.

빠른 그레인 검증 체크리스트

빌드 전에 이해관계자들에게 대답할 수 있는 질문을 하세요:

  1. “당신이 ‘주문’이라고 말할 때, 전체 주문을 의미하나요 아니면 그 안의 각 품목을 의미하나요?”
  2. “두 레벨(주문 및 품목)에서 모두 리포트해야 하나요? 어느 쪽이 주(primary)인가요?”
  3. “다음 분기 상위 5개 질문은 무엇인가요? 그것들이 품목 수준 세부를 요구하나요?”
  4. “하나의 이벤트가 여러 것에 속할 수 있나요(여러 캠페인, 여러 카테고리)?”
  5. “무엇을 절대 중복 집계하면 안 되나요(수익, 사용자, 세션) 그리고 어떤 그레인에서 안전한가요?”

키와 정체성: 자연 키 vs 서로게이트, 그리고 그 중요성

키는 모델이 “이 행이 현실 세계의 다른 행과 동일한 것”인지 결정하는 방법입니다. 잘못하면 조인이 엉키고 증분 로드가 느려지며 새 시스템 통합이 체크리스트가 아니라 협상이 됩니다.

자연 키 vs 서러게이트 키(평이한 언어)

자연 키는 비즈니스나 소스 시스템에 이미 존재하는 식별자입니다—예: 송장 번호, SKU, 이메일 주소, CRM의 customer_id. 서로게이트 키는 내부에서 생성한 ID(종종 정수나 해시)로 창고 밖에서는 의미가 없습니다.

자연 키는 이미 존재하고 이해하기 쉬워 매력적입니다. 서로게이트 키는 잘 관리하면 안정적이어서 매력적입니다.

시간이 지나면서의 안정성: ID가 바뀌면 무슨 일이 일어나는가

소스 시스템이 피할 수 없이 변경될 때 락인이 드러납니다:

  • CRM 마이그레이션으로 고객 ID가 재할당될 수 있습니다.
  • 제품 카탈로그가 SKU를 재번호화할 수 있습니다.
  • 인수합병으로 두 개의 customer_id 네임스페이스가 겹칠 수 있습니다.

웨어하우스 전체에서 자연 키를 사용하면 이러한 변경이 팩트, 디멘션, 다운스트림 대시보드 전반에 파급될 수 있습니다. 역사적 메트릭이 갑자기 바뀌는 일이 발생할 수 있습니다.

서로게이트 키를 사용하면 새로운 소스 ID를 기존 서로게이트 정체성에 매핑함으로써 소스 식별자가 바뀌어도 웨어하우스 정체성을 안정적으로 유지할 수 있습니다.

병합/중복 제거 로직: 정체성은 단순한 조인이 아니라 정책이다

실제 데이터는 병합 규칙이 필요합니다: “동일한 이메일 + 동일한 전화 = 동일 고객”, “가장 최신 레코드를 우선”, “확인될 때까지 둘 다 유지” 등. 이 중복 제거 정책은 다음에 영향을 줍니다:

  • 조인: 정체성 해소가 늦게 일어나면(예: BI 레이어에서) 모든 조인은 조건부가 되고 일관성이 떨어집니다.
  • 증분 로드: 병합이 과거를 덮어쓸 수 있으면 백필이나 ‘재키(keying) 변경’ 로직이 필요해 비용과 위험이 큽니다.

실용적 패턴은 별도의 매핑 테이블(종종 정체성 맵이라고 불림)을 유지해 여러 소스 키가 하나의 웨어하우스 정체성으로 어떻게 합쳐지는지 추적하는 것입니다.

데이터 공유 및 신규 제품 통합에 대한 결과

데이터를 파트너와 공유하거나 인수한 회사를 통합할 때, 키 전략이 작업량을 결정합니다. 한 시스템에 묶인 자연 키는 잘 돌아다니지 않습니다. 서로게이트 키는 내부에서 잘 작동하지만, 다른 쪽에서 조인하려면 일관된 크로스워크를 공개해야 합니다.

어느 쪽이든 키는 단순한 컬럼 선택이 아니라 비즈니스 엔터티가 변화 속에서 어떻게 살아남을지를 결정하는 약속입니다.

시간과 변화 모델링: 미래의 당신이 감사할 것이다

시간은 “단순한” 모델을 비용이 많이 드는 것으로 바꾸는 곳입니다. 대부분의 팀은 현재 상태 테이블(고객/주문/티켓당 한 행)으로 시작합니다. 쿼리하기 쉽지만 나중에 필요할 답을 조용히 삭제합니다.

‘히스토리’의 의미를(필요하기 전에) 결정하세요

일반적으로 세 가지 옵션이 있으며, 각각은 다른 도구와 비용에 락인을 만듭니다:

  • 덮어쓰기(스냅샷): 저장소가 가장 작고 테이블 단순하지만 추적성이 약함.
  • 추가 전용 이벤트(불변 로그): 감사에 가장 강하지만 쿼리가 더 복잡(중복 제거, 세션화, ‘최신 상태’ 계산 필요).
  • SCD(점진적 변경 차원): 엔터티에 대한 중간 지점, 보통 effective_start, effective_end, is_current 플래그 사용.

만약 언젠가 “당시 우리가 무엇을 알고 있었나?”가 필요할 가능성이 있다면 덮어쓰기만으로는 안 됩니다.

현재 상태만으로는 부족한 경우

팀들은 보통 다음 상황에서 누락된 히스토리를 발견합니다:

  • 감사 및 재무: “청구 시점의 가격/할인/세금은 무엇이었나?”
  • 고객 지원: “사건이 발생했을 때 어떤 주소 또는 요금제가 활성화되어 있었나?”
  • 규정 준수 및 신뢰: “그 날짜에 누가 접근 권한을 가지고 있었나?”

사후에 이를 재구성하는 것은 고통스럽습니다. 상류 시스템들이 이미 진실을 덮어썼을 수 있기 때문입니다.

시간에는 날카로운 모서리가 있다: 존, 유효일, 지연 데이터

시간 모델링은 단순한 타임스탬프 컬럼 이상입니다.

  • 타임존: 모호함이 없도록 순간(UTC)을 저장하고, 필요하면 원래 로컬 타임존도 보관하세요.
  • 유효일 vs 이벤트 시간: “유효”는 비즈니스 현실(계약 시작), “이벤트”는 기록된 시점입니다.
  • 지연 도착 데이터와 백필: append-only와 SCD 패턴은 정정을 처리하기 쉽고, 덮어쓰기는 종종 취약한 재구성으로 이어집니다.

비용과 단순성의 트레이드오프

히스토리는 저장소와 컴퓨트 비용을 증가시키지만 나중에 복잡성을 줄이기도 합니다. 추가 전용 로그는 수집을 저렴하고 안전하게 만들 수 있고, SCD 테이블은 일반적인 ‘as of’ 쿼리를 간단하게 만듭니다. 오늘의 대시보드만이 아니라 비즈니스가 물어볼 질문과 일치하는 패턴을 선택하세요.

정규화 vs 차원 모델: 누구에게 최적화할 것인가

안전한 스키마 변경 계획
Planning Mode로 테이블을 변경하기 전에 데이터 단위, 이력, 지표 변화를 매핑하세요.

정규화와 차원 모델링은 단지 “스타일”이 아닙니다. 이들은 시스템이 친절하게 만드는 대상—파이프라인을 유지하는 데이터 엔지니어인지, 매일 질문에 답하는 사람인지—을 결정합니다.

정규화 모델: 중복 감소, 업데이트 고통 감소

정규화 모델(종종 3NF)은 데이터를 더 작은 관련 테이블로 분해하여 각 사실을 한 번만 저장합니다. 목표는 중복을 피하고 그로 인한 문제를 줄이는 것입니다:

  • 고객 주소가 바뀌면 한 곳만 업데이트하면 됩니다—열 곳의 리포트를 고칠 필요 없음.
  • 제품명이 수정되면 대시보드 전반에 걸쳐 철자가 일관되지 않는 일이 줄어듭니다.

이 구조는 데이터 무결성에 좋고 업데이트가 자주 일어나는 시스템에 유리합니다. 엔지니어링 중심 팀에 적합합니다.

차원 모델(스타 스키마): 속도와 사용성

차원 모델링은 분석을 위해 데이터를 재구성합니다. 일반적 스타 스키마는:

  • 팩트 테이블(주문, 세션, 결제 같은 이벤트나 측정)
  • 여러 디멘션 테이블(고객, 제품, 날짜, 지역 같은 설명적 맥락)

이 레이아웃은 빠르고 직관적입니다: 분석가는 복잡한 조인 없이 디멘션으로 필터/그룹할 수 있고, BI 도구는 이를 잘 이해합니다. 제품팀도 혜택을 봅니다—일반적인 메트릭 쿼리가 쉽고 오해하기 어려워 자가 서비스 탐색이 현실적이 됩니다.

누가 혜택을 보는가?

정규화 모델은 다음에 최적화됩니다:

  • 데이터 플랫폼 유지보수자(깨끗한 업데이트, 중복 감소)
  • 다양한 다운스트림 사용에 대한 일관성

차원 모델은 다음에 최적화됩니다:

  • 분석가와 분석 엔지니어(단순한 SQL)
  • BI 도구(직관적 관계)
  • 제품팀(더 빠른 응답, 자가 서비스성 증가)

락인은 실제입니다: 수십 개의 대시보드가 스타 스키마에 의존하면 그레인이나 디멘션을 바꾸는 것은 정치적·운영상 비용이 큽니다.

실용적 하이브리드: 정규화된 스테이징 + 큐레이티드 마트

갈등을 줄이는 일반적 접근은 두 레이어를 명확한 책임으로 유지하는 것입니다:

  • 정규화된 스테이징/코어: 데이터를 최소한으로 변형하여 보관하고 소스 보존, 중복 감소
  • 큐레이티드 차원 마트: 가장 가치 있는 사용 사례(수익, 성장, 리텐션)를 위한 스타 스키마 게시, 안정적인 메트릭 정의 제공

이 하이브리드는 기록 시스템을 유연하게 유지하면서 비즈니스에 필요한 속도와 사용성을 제공해 한 모델이 모든 일을 하도록 강요하지 않습니다.

이벤트 중심 vs 엔터티 중심 모델

이벤트 중심 모델은 어떤 일이 발생했는지를 설명합니다: 클릭, 결제 시도, 발송 업데이트, 지원 티켓 회신. 엔터티 중심 모델은 무엇인지(고객, 계정, 제품, 계약)를 설명합니다.

무엇을 최적화하는가

엔터티 중심 모델(고객, 제품, 구독 같은 현재 상태 컬럼이 있는 테이블)은 운영 리포팅과 “활성 계정 수는?” 또는 “각 고객의 현재 요금제는?” 같은 단순 질문에 적합합니다. 또한 직관적입니다: 사물당 한 행.

이벤트 중심 모델(추가 전용 팩트)은 시간에 따른 분석에 최적화되어 있습니다: “무엇이 바뀌었나?” “어떤 순서였나?” 소스 시스템에 더 가깝기 때문에 나중에 새로운 질문을 추가하기가 쉽습니다.

이벤트 모델이 더 유연할 수 있는 이유

잘 설명된 이벤트 스트림(타임스탬프, 액터, 오브젝트, 컨텍스트 포함)을 유지하면 핵심 테이블을 재모델링하지 않고도 새 질문에 답할 수 있습니다. 예: 나중에 “첫 가치 발생 시점(first value moment)”, “단계 간 이탈(drop-off)”, “무료 체험 시작에서 첫 결제까지의 시간” 등을 기존 이벤트에서 도출할 수 있습니다.

한계도 있습니다: 이벤트 페이로드에 핵심 속성(예: 어떤 마케팅 캠페인이 적용되었는지)이 전혀 캡처되지 않았다면 나중에 이를 새로 만들어낼 수는 없습니다.

숨은 비용

이벤트 모델은 더 무겁습니다:

  • 볼륨: 행 수가 훨씬 많아 저장소와 컴퓨트 비용 상승
  • 지연/순서 오류: 정정과 백필 규칙 필요
  • 세션화 및 상태 재구성: 이벤트를 세션이나 활성 사용자, 현재 상태로 바꾸는 작업은 복잡하고 비용이 들 수 있음

엔터티가 여전히 필수인 곳

이벤트 우선 아키텍처라도 accounts, contracts, product catalog 같은 안정적인 엔터티 테이블은 필요합니다. 이벤트는 이야기를 제공하고, 엔터티는 등장인물을 정의합니다. 결정적 락인은 얼마나 많은 의미를 “현재 상태”로 인코딩할지 vs 히스토리에서 유도할지입니다.

시맨틱 레이어와 메트릭: 비즈니스 의미 수준의 락인

지표 버전을 문제없이 관리
revenue_v1 vs revenue_v2를 나란히 비교하는 이해관계자 검토 앱을 만드세요.

시맨틱 레이어(메트릭 레이어)는 원시 테이블과 사람들이 실제로 사용하는 숫자 사이의 번역지입니다. 메트릭과 슬라이싱 가능한 디멘션(날짜, 지역, 제품) 및 항상 적용되어야 할 필터를 한 번 정의하면, 각 대시보드나 분석가가 로직을 다시 구현하는 일을 줄일 수 있습니다.

메트릭 정의는 비즈니스의 API가 된다

메트릭이 널리 채택되면 비즈니스를 위한 API처럼 동작합니다. 수백 개의 리포트, 알림, 실험, 예측, 보너스 플랜이 이에 의존할 수 있습니다. 나중에 정의를 바꾸면 SQL은 여전히 동작하더라도 신뢰가 깨질 수 있습니다.

락인은 기술적 문제만이 아닙니다—사회적 문제입니다. 예를 들어 “Revenue”가 항상 환불을 제외했다면, 순수익(net revenue)으로 갑자기 바꾸면 트렌드가 하루아침에 이상해 보입니다. 사람들은 무엇이 바뀌었는지 묻기도 전에 데이터를 믿지 않게 됩니다.

의미가 굳어지는 곳

작은 선택들이 빠르게 굳어집니다:

  • 명명: orders는 주문 수 집계라는 의미를 암시합니다. 모호한 이름은 일관성 없는 사용을 초대합니다.
  • 디멘션: 메트릭을 order_date로 그룹핑할지 ship_date로 할지 결정하면 내러티브와 운영 결정이 달라집니다.
  • 필터: “내부 계정 제외” 또는 “유료 인보이스만” 같은 기본 필터는 잊기 쉽고 나중에 되돌리기 어렵습니다.
  • 어트리뷰션 규칙: “채널별 가입”은 퍼스트터치, 라스트터치, 7일 윈도우 중 기본값 하나를 정할 수 있고, 이는 어떤 팀이 성공적으로 보이는지를 결정할 수 있습니다.

버전 관리 및 변경 소통

메트릭 변경을 제품 릴리스처럼 다루세요:

  • 메트릭을 명시적으로 버전 관리하세요: revenue_v1, revenue_v2를 만들고 전환 기간 동안 둘 다 제공하세요.
  • 계약 문서화: 정의, 포함/제외 항목, 어트리뷰션 윈도우, 허용 차원을 문서화하세요.
  • 파괴적 변경은 미리 알리기: 문서 릴리스 노트, 마이그레이션 일정, 병렬 검증 대시보드를 제공하세요.
  • 날짜로 폐기: “v1은 Q2 이후 제거”처럼 명시적으로 정하세요.

시맨틱 레이어를 의도적으로 설계하면 의미를 변경할 때 모두가 놀라지 않도록 락인 관련 고통을 줄일 수 있습니다.

스키마 진화: 파괴적 변경을 피하는 방법

모든 스키마 변경이 동일하지 않습니다. 새 NULL 허용 컬럼을 추가하는 것은 보통 낮은 위험입니다: 기존 쿼리는 이를 무시하고 다운스트림 잡은 계속 실행되며, 나중에 백필할 수 있습니다.

문맥이 바뀐 기존 컬럼의 의미를 바꾸는 것은 비용이 많이 드는 유형입니다. 예를 들어 status가 이전에는 "결제 상태(payment status)"를 의미했는데 지금은 "주문 상태(order status)"를 의미하면, 모든 대시보드와 알림, 조인이 은밀하게 잘못되었지만 소리는 나지 않습니다. 의미 변경은 시끄러운 실패가 아니라 은밀한 데이터 버그를 만듭니다.

공유 테이블을 계약처럼 다루기

여러 팀이 소비하는 테이블에는 명시적 계약과 테스트를 정의하세요:

  • 예상 스키마: 컬럼 이름, 타입, 컬럼 제거 가능 여부
  • 허용 null: 항상 있어야 하는 필드 vs 선택적 필드
  • 허용 값: enum(예: pending|paid|failed) 및 숫자 범위

이는 데이터 계약 테스트와 같습니다. 우발적 드리프트를 막고 “파괴적 변경”을 명확한 카테고리로 만듭니다.

효과가 있는 하위 호환 패턴

모델을 진화시켜야 할 때는 구·신 소비자가 공존할 수 있는 기간을 목표로 하세요:

  • 폐기(deprecate), 삭제하지 말기: 구 컬럼을 정의된 창 동안 유지하고 문서에서 사용 중단으로 표시하세요.
  • 이중 쓰기(dual-write): 전환이 끝날 때까지 구/신 필드나 테이블을 모두 채우세요.
  • 별칭 뷰(alias views): 기본 테이블이 바뀌더라도 오래된 이름을 보존하는 안정적 뷰를 제공하세요.

소유권과 승인

공유 테이블에는 명확한 오너가 필요합니다: 누가 변경을 승인하는가, 누가 알림을 받는가, 롤아웃 프로세스는 무엇인가? 오너 + 리뷰어 + 폐기 일정 같은 경량 정책이 도구 어느 것보다 파괴 방지에 효과적입니다.

성능과 비용 제약이 모델을 형성하는 방식

데이터 모델은 단순한 논리 다이어그램이 아니라 쿼리가 어떻게 실행될지, 비용이 얼마나 들지, 나중에 무엇이 고치기 어려운지에 대한 물리적 배팅입니다.

파티셔닝과 클러스터링은 조용히 쿼리 동작을 좌우한다

파티셔닝(보통 날짜별)과 클러스터링(자주 필터링하는 키, 예:customer_id 또는 event_type)은 특정 쿼리 패턴에 보상을 주고 다른 패턴을 벌합니다.

예: event_date로 파티셔닝하면 “최근 30일” 필터가 저렴하고 빠르지만, 많은 사용자가 긴 기간에 걸쳐 account_id로 슬라이스하면 여러 파티션을 스캔하게 되어 비용이 폭증하고 팀들은 요약 테이블이나 추출물을 만들어 모델을 더욱 고착시키는 해결책을 고안하게 됩니다.

넓은 테이블 vs 많은 조인: 속도와 유연성

넓은(비정규화된) 테이블은 BI 도구에 친화적입니다: 조인이 적고 놀람이 적으며 “첫 차트까지의 시간”이 빨라집니다. 또한 큰 테이블에 대한 반복 조인을 피하면 쿼리당 비용이 저렴할 수 있습니다.

대신 단점은 데이터 중복입니다. 저장소가 늘고 업데이트가 복잡해지며 일관된 정의를 강제하기 어려워집니다.

강하게 정규화된 모델은 중복을 줄이고 무결성을 개선할 수 있지만, 반복 조인으로 쿼리가 느려지고 비기술 사용자들이 직접 리포트를 만들 때 경험이 나빠질 수 있습니다.

증분 로드는 스키마 선택을 제약한다

대부분 파이프라인은 증분으로(신규 행 또는 변경된 행) 로드됩니다. 이는 안정적인 키와 append-친화적 구조에서 가장 잘 동작합니다. 과거를 자주 재작성해야 하는 모델(예: 많은 파생 컬럼을 재구성해야 하는 경우)은 비용과 운영 위험이 큽니다.

데이터 품질 검사, 백필, 재처리

모델은 무엇을 검증할 수 있고 무엇을 고칠 수 있는지를 결정합니다. 메트릭이 복잡한 조인에 의존하면 품질 검사는 локализ화하기 어려워집니다. 테이블이 백필 방식(일별, 소스 배치)에 맞춰 파티셔닝되어 있지 않으면 재처리는 훨씬 많은 데이터를 스캔·재작성해야 해서 일상적 수정이 주요 사고로 변할 수 있습니다.

나중에 바꾸는 것은 얼마나 어려운가? 마이그레이션 현실 점검

모델을 계약으로 전환
데이터 단위와 키, 계약을 한곳에 문서화하는 경량 UI를 만드세요.

데이터 모델을 나중에 바꾸는 것은 거의 ‘리팩터’가 아닙니다. 사람들은 여전히 그 도시(시스템)에 살고 있고: 리포트는 계속 작동해야 하고, 정의는 일관되어야 하며, 오래된 가정은 대시보드·파이프라인·보상에 깊게 박혀 있습니다.

보통 마이그레이션을 강제하는 요인

다음과 같은 트리거가 반복적으로 나타납니다:

  • 새 웨어하우스/레이크하우스(비용, 성능, 벤더 전략)가 현재 스키마와 깔끔하게 매핑되지 않을 때
  • M&A(인수합병) 또는 분할로 두 비즈니스가 비호환 고객 ID, 제품 계층, 메트릭 정의를 가져올 때
  • 새 제품 라인/채널이 기존 그레인을 깨뜨릴 때(예: 구독을 모델링했는데 사용량 기반 과금이 추가됨)

“빅뱅”보다 안전한 실행 계획

가장 낮은 위험 접근법은 마이그레이션을 엔지니어링 프로젝트이자 변경 관리 프로젝트로 취급하는 것입니다.

  1. 병렬 모델 운영: 구 스키마는 안정적으로 유지하면서 신모델을 병행 구축.
  2. 지속적 조정(reconcile): 병렬 출력물을 게시하고 차이를 초기에 조사.
  3. 신중한 커트오버 계획: 가치가 높고 복잡도가 낮은 사용 사례부터 마이그레이션; 정의 동결; 날짜 소통.

내부 데이터 앱(관리 도구, 메트릭 탐색기, QA 대시보드)이 있다면 이를 일급 마이그레이션 소비자처럼 다루는 것이 도움이 됩니다. 팀들은 가끔 Koder.ai 같은 빠른 앱 제작 워크플로를 사용해 계약 검사 UI, 대조 대시보드, 이해관계자 검토 도구를 병렬 실행 중에 신속하게 만들기도 합니다.

성공을 어떻게 판단하나

성공은 “새 테이블이 존재한다”가 아닙니다. 성공은:

  • 쿼리 동등성: 중요한 쿼리가 합의된 허용 범위 내에서 같은 답을 반환
  • 메트릭 동등성: 헤드라인 KPI가 정의에 따라 일치
  • 사용자 채택: 분석가와 이해관계자가 실제로 전환하고 구 대시보드가 퇴출됨

예산과 일정

마이그레이션은 재조정과 이해관계자 승인 때문에 예상보다 더 많은 시간을 소비합니다. 비용 계획을 1급 작업으로 다루세요(인력 시간, 이중 운영 컴퓨트, 백필). 트레이드오프와 일정 정리가 필요하면 /pricing을 참조하세요.

되돌릴 수 있게 설계하기: 실용적 반(反)락인 전술

되돌릴 수 있게 설계하는 것은 모든 미래 요구를 예측하는 것이 아니라 변경을 저렴하게 만드는 것입니다. 목표는 도구(웨어하우스→레이크하우스), 모델링 접근(차원→이벤트 중심), 메트릭 정의의 변화가 전체 재작성으로 이어지지 않도록 하는 것입니다.

“되돌릴 수 있게 하라” 원칙

모델을 명확한 계약이 있는 모듈형 레이어로 취급하세요.

  • 원시 팩트와 비즈니스 준비 테이블 분리: 불변 수집 레이어, 큐레이티드 코어 엔터티/이벤트, 마트로 분리.
  • 경계에 계약 정의: 공유 테이블에 대해 안정적인 컬럼 이름, 타입, 그레인을 정하고 나머지는 변경 가능하게.
  • 의도적 버전 관리: 계약을 깨야 할 때는 v2를 병렬 제공하고 소비자 마이그레이션 후 v1을 폐기.

사전 커밋 체크리스트(신모델 출시 전 사용)

  • 그레인을 한 문장으로 표현하세요.
  • 주요 키(또는 고유성 규칙)는 무엇이며 어떻게 생성되는가?
  • 어떤 필드가 불변이고 어떤 필드가 수정 가능한가?
  • 시간을 어떻게 표현할 것인가(유효일, 이벤트 시간, 스냅샷 시간)?
  • 예상 소비자(대시보드, ML, 리버스 ETL)와 그들의 레이턴시 요구사항은?
  • 그레인이나 키 전략이 바뀌면 마이그레이션 계획은?

놀라움을 방지하는 경량 거버넌스

작지만 실효 있는 거버넌스를 유지하세요: 메트릭 정의가 포함된 데이터 사전, 핵심 테이블별 명시된 오너, 무엇이 왜 누가 변경했는지 기록하는 간단한 변경 로그(레포의 Markdown 파일 등).

실용적 다음 단계

작은 도메인(예: “orders”)에서 이 패턴을 파일럿하고 v1 계약을 게시한 뒤 최소 하나의 계획된 변경을 버전 프로세스로 실행해 보세요. 잘 되면 템플릿을 표준화하고 다음 도메인으로 확장하세요.

자주 묻는 질문

공급업체 락인(vendor lock-in) 외에 ‘데이터 모델 락인’은 무엇을 의미하나요?

락인(lock-in)은 많은 다운스트림 소비자가 테이블에 의존하게 되어 변경이 너무 위험하거나 비용이 많이 들어서 더 이상 바꾸지 못하는 상태를 말합니다.

창고나 ETL 도구를 바꾸더라도, 곡물(grain), 키, 히스토리, 메트릭 정의에 담긴 의미는 대시보드, ML 피처, 통합, 그리고 공유된 비즈니스 언어 전반에 걸쳐 계약처럼 남아 있습니다.

데이터 모델을 깨지기 쉬운 것 대신 안전한 계약으로 만들려면 어떻게 해야 하나요?

널리 사용되는 각 테이블을 인터페이스처럼 취급하세요:

  • 테이블의 grain(“한 행은 ___ 당 하나”)을 정의하세요.
  • 기본 키/고유성 규칙을 선언하세요.
  • 필수 필드 vs 선택 필드와 허용 값 범위를 문서화하세요.
  • 메트릭 정의를 별도로 게시해 의미가 흐려지지 않도록 하세요.

목표는 ‘절대 변경하지 않기’가 아니라 ‘놀라움 없이 변경하기’입니다.

팩트 테이블에 적절한 grain을 어떻게 선택하나요?

나중에 요청될 질문을 어색한 우회 없이 답할 수 있는 grain을 선택하세요.

실용적 점검:

  • 다음 분기에 가장 많이 물어볼 질문을 나열하세요.
  • 결코 중복 집계되어서는 안 되는 항목(수익, 사용자, 주문)을 식별하세요.
  • 집계 수준(예: 주문 수준)과 세부 수준(예: 품목 수준)을 모두 필요로 하는지 확인하세요.

일대다 관계의 ‘하나’ 쪽만 모델링하면 나중에 백필이나 중복된 파생 테이블에 비용을 치르게 될 가능성이 큽니다.

자연 키와 서로게이트 키는 언제 사용해야 하나요?

자연 키(송장 번호, SKU, 소스의 customer_id)는 이해하기 쉽지만 변경되거나 충돌할 수 있습니다.

대조적으로, 서로게이트 키는 내부에서 생성되는 안정적 ID로서 소스 ID 변경에 대응해 매핑을 유지하면 안정적인 내부 정체성을 제공합니다.

예상되는 CRM 마이그레이션, M&A, 또는 여러 ID 네임스페이스가 있다면:

  • 정체성 매핑 테이블(크로스워크)을 계획하세요.
  • 명시적 중복 병합 규칙(identity is a policy)을 마련하세요.
히스토리(이벤트, 스냅샷, SCD)를 언제 저장해야 하나요?

만약 언젠가 ‘그때 우리는 무엇을 알고 있었나?’라는 질문이 나올 수 있다면 덮어쓰기(overwrite)만으로는 부족합니다.

일반 옵션:

  • 덮어쓰기(현재 상태): 저장 소모가 적고 단순하지만 추적성이 약함.
  • 추가 전용 이벤트(append-only): 감사에 강하지만 ‘최신 상태’ 쿼리는 더 복잡함.
  • SCD(Type 2 등): effective_start/effective_endis_current 플래그로 ‘as of’ 조회에 적절.

감사, 재무, 고객 지원, 규정 준수 관련 질문을 기준으로 선택하세요—오늘의 대시보드만 보고 결정하지 마세요.

시간과 타임스탬프 모델링에서 가장 큰 함정은 무엇인가요?

시간 문제는 대부분 모호함에서 옵니다, 단순히 컬럼이 없어서가 아닙니다.

실무 권장 기본값:

  • 이벤트 타임스탬프는 모호하지 않게(대부분 UTC) 저장하세요.
  • 로컬 시간으로 리포팅해야 하면 원래 타임존도 보관하세요.
  • 이벤트 시간(발생 시각)과 유효 시간(effective)(업무상 유효 시점)을 분리하세요.
  • 지연 도착 데이터나 정정은 append + 백필 규칙 또는 SCD 업데이트 방식으로 처리할 계획을 세우세요.
메트릭 정의가 왜 락인을 만들며, 메트릭 드리프트는 어떻게 막나요?

시맨틱 레이어(메트릭 레이어)는 원시 테이블과 실제 사용 숫자 사이의 번역표입니다. 메트릭을 한 번 정의하면 수백 개의 보고서, 알림, 실험, 예측, 성과 보상 등이 그것에 의존할 수 있습니다. 정의 변경은 기술적 변화뿐 아니라 사회적 신뢰의 문제를 만듭니다.

정책:

  • 메트릭을 한 곳에서 정의하고 기본 필터와 허용 차원을 포함하세요.
  • 모호한 이름을 피하세요(orders vs order_items).
  • 파괴적 변경은 버전 관리(revenue_v1, revenue_v2)하고 병렬로 운영하세요.

이렇게 하면 락인이 흩어진 SQL 대신 관리되는 문서화된 계약으로 바뀝니다.

소비자(다운스트림)를 깨지 않으면서 스키마를 진화시키는 안전한 전략은 무엇인가요?

공유 테이블에는 명시적 계약과 테스트가 필요합니다:

  • 예상 스키마(컬럼 이름, 타입, 제거 여부)
  • 허용 null 여부
  • 허용 값(예: enum)과 숫자 범위

스키마 변경 시 안전한 패턴:

  • 컬럼 의미를 바꾸지 말고 새 nullable 컬럼을 추가하세요.
  • 삭제 대신 deprecate(기간 명시)를 사용하세요.
  • 전환 기간 동안 old/new를 동시에 쓰는 dual-write를 고려하세요.
  • 호환성 레이어로 안정적인 뷰(alias views)를 제공하세요.
성능 및 비용 제약이 데이터 모델 결정에 어떤 영향을 미치나요?

물리적 선택은 사용자 행동을 유도합니다:

  • 파티셔닝/클러스터링은 특정 필터를 보상하고 다른 필터를 벌합니다.
  • 넓은(denormalized) 테이블은 BI 이용을 빠르게 하지만 데이터 중복과 업데이트 복잡도를 증가시킵니다.
  • 정규화된 모델은 무결성에는 유리하지만 조인이 많아질수록 쿼리가 느려질 수 있습니다.

우선적으로 발생하는 접근 패턴(예: 최근 30일, account_id 기준)을 기준으로 설계하고, 백필/재처리 방식에 맞춰 파티셔닝 전략을 정하세요.

나중에 새로운 데이터 모델로 마이그레이션하는 가장 현실적인 방법은 무엇인가요?

모델 변경은 대부분 ‘리팩터’가 아니라 사람들이 여전히 살고 있는 도시를 옮기는 일과 비슷합니다: 보고서는 계속 돌아가야 하고, 정의는 일관되어야 하며, 기존 가정은 대시보드와 파이프라인, 보상 체계에 깊게 박혀 있습니다.

안전한 접근:

  • 병렬 모델을 운영하세요(구 모델은 안정적으로 유지하면서 신모델을 병행 구축).
  • 결과를 지속적으로 대조하고 초기에 차이를 조사하세요.
  • 사용 사례별로 전환을 계획하고 중요한 것부터 먼저 옮기세요.

성공 판단 기준:

  • 핵심 쿼리의 결과가 합의된 허용 오차 내에서 일치하는지
  • 주요 KPI가 정의에 따라 일치하는지
  • 분석가와 이해관계자가 실제로 전환하고 구 대시보드가 퇴출되는지

비용과 일정을 계획할 때는 이중 운영 컴퓨트와 백필 비용, 이해관계자 승인이 주요 병목임을 예산에 반영하세요. 교차 시나리오와 트레이드오프를 정리해야 하면 /pricing을 참고하세요.

되돌릴 수 있게 설계하려면 어떤 실용적 전술을 써야 하나요?

변경을 싸게 만드는 것이 목적입니다. 모든 미래 요구를 예측하는 것이 아니라, 변화를 저렴하게 만드는 설계를 하세요.

원칙:

  • 원시 수집 레이어와 비즈니스 준비된 테이블, 마트 등 모듈화된 레이어로 구분하세요.
  • 경계마다 계약을 정의하세요(안정적인 컬럼 이름, 타입, grain).
  • 파괴적 변경이 필요하면 의도적으로 버전 관리하고 병렬로 제공하세요.

사전 체크리스트:

  • 한 문장으로 표현한 grain은 무엇인가?
  • 기본 키(혹은 고유성 규칙)는 무엇이며 어떻게 생성되는가?
  • 어떤 필드가 불변인지, 어떤 필드가 수정 가능한가?
  • 시간을 어떻게 표현할 것인가(유효일, 이벤트 시간, 스냅샷 시간)?
  • 예상 소비자(대시보드, ML, 리버스 ETL)와 레이턴시 요구사항은?
  • grain이나 키 전략이 바뀌면 마이그레이션 계획은?

경량 거버넌스: 데이터 사전, 핵심 테이블별 오너 명시, 변경 로그(레포의 Markdown 파일 등)를 운영하세요.

실용적 다음 단계: ‘orders’ 같은 작은 도메인에서 템플릿을 파일럿하고 v1 계약을 게시한 뒤, 버전 프로세스를 통해 한 번 계획된 변경을 실행해 보세요. 성공하면 템플릿을 표준화해 다음 도메인으로 확장하세요.

Related posts