DW 유저 상태 Fact 모델링: 상태를 구간으로 저장하는 Interval Table
이 글은 유저 상태 스냅샷 포스트 와 시리즈 개요편 에서 이어지는 내용입니다. 앞선 글을 아직 안 보셨다면 먼저 보고 오셔도 좋습니다.
스냅샷 모델링을 보고 아래와 같은 의문을 가지실 수 있습니다.
- inactive 기간을 매일 한 줄씩 저장하지 않고 표현할 수 없나요?
- 특정 날짜 상태는 알고 싶은데 daily snapshot 은 너무 무겁지 않나요?
- 같은 상태가 며칠 유지됐는지를 더 자연스럽게 저장하는 방법은 없나요?
이런 질문에는 Interval Table 이 꽤 좋은 답이 됩니다.
Interval Table은 무엇인가
이 모델은 상태를 일별 row로 저장하지 않고, 같은 상태가 유지된 구간 으로 저장합니다.
예를 들면 이런 식입니다.
| user_id | state | start_day | end_day |
|---|---|---|---|
| 1001 | NEW | 2025-03-01 | 2025-03-01 |
| 1001 | RETAINED | 2025-03-02 | 2025-03-02 |
| 1001 | INACTIVE | 2025-03-03 | 2025-03-09 |
| 1001 | REACTIVATED | 2025-03-10 | 2025-03-10 |
즉 INACTIVE 를 7줄로 저장하는 대신, 2025-03-03 ~ 2025-03-09 하나의 구간으로 표현합니다.
장점
- 저장량이 크게 줄어듭니다
- inactive 기간 표현이 자연스럽습니다
- 특정 날짜 상태 복원도 가능합니다
예를 들어 2025-03-05 상태를 보고 싶으면 아래처럼 찾을 수 있습니다.
WHERE start_day <= '2025-03-05'
AND end_day >= '2025-03-05'
즉 daily snapshot처럼 모든 날짜를 다 적지는 않지만, 특정 날짜 상태는 여전히 찾을 수 있습니다.
단점
- 적재 로직이 조금 더 까다롭습니다
- 상태 구간이 이어질 때 merge/split 처리가 필요합니다
- 처음 보는 사람에게는 daily snapshot보다 덜 직관적일 수 있습니다
즉 저장 효율은 좋지만, 구현 난이도는 조금 올라갑니다.
운영에서 특히 조심할 점
Interval Table 은 상태 구간을 나누고 붙이는 로직이 핵심입니다.
특히 아래를 조심해야 합니다.
- 연속 구간 merge 조건
- 지연 로그 유입 시 기존 구간 재분할 방식
- 특정 날짜 상태 복원 쿼리의 성능
즉 row 수는 줄어들지만, 구간 관리 로직은 더 정교해져야 합니다.
언제 잘 맞는가
- inactive 기간 관리가 중요할 때
- daily snapshot 저장량이 부담될 때
- 특정 날짜 상태 복원이 여전히 필요할 때
상태를 매일 다 적는 것이 부담스럽고, 그렇다고 transition만으로는 부족하다면 Interval Table은 꽤 좋은 타협안입니다.
참조 링크:
댓글 남기기
댓글 목록
관리자 보기