1. 문제 상황: 노후 리포트가 만든 운영 리스크
기존 리포트는 HTML 기반으로 운영되면서 시간이 지날수록 유지보수와 운영 한계가 뚜렷해졌다.
리포트가 단순 조회 화면에 가까운 형태로 관리되어, 데이터 생성 기준과 필터링 조건, 권한 체계를 추적하기 어려웠다.
이 때문에 리포트를 수정할 때마다 기존 로직을 다시 확인해야 했고, 작은 조건 변경에도 운영 부담이 컸다.
보안과 권한 관리에서도 문제가 있었다.
접근 권한이 데이터 기준으로 체계화되어 있지 않고 기존 화면과 운영 방식에 의존하고 있어, 사용자별 접근 범위를 명확히 통제하기 어려웠다.
운영 리포트에서 데이터 접근 권한은 보안 리스크와 직접 연결되는 요소이므로 개선이 필요하다고 판단했다.
과거 데이터 조회와 이력 분석에도 제약이 있었다.
특정 시점의 데이터를 다시 확인하거나 기간을 조정해 분석하기 어려웠고,
일부 데이터 생성 과정은 수동 실행에 의존하고 있었다. 실행 누락이나 조건 불일치가 발생할 가능성이 있어 리포트 신뢰도와 운영 안정성에도 영향을 줄 수 있었다.
따라서 이번 업무는 단순한 리포트 교체가 아니라,
노후화된 HTML 리포트를 데이터 생성, 조회, 권한 관리, 운영 자동화까지 고려한 관리 가능한 구조로 재설계하는 작업이었다.
2. 목표: 리포트를 “관리 가능한 데이터 구조”로 전환하기
이번 업무의 목표는 오래된 HTML 리포트를 다른 화면으로 바꾸는 데 있지 않았다.
리포트 운영 방식을 데이터 마트 관점에서 재구성해, 안정적으로 조회하고 지속적으로 관리할 수 있는 구조를 만드는 것이 핵심이었다.
이를 해결하기 위해 다음 기준을 중심으로 개선 방향을 잡았다.

이 과정에서 담당자들과 Slack을 통해 리포트에 사용될 정의와 지표 기준을 확인했다.
같은 데이터라도 담당 조직이나 리포트 목적에 따라 해석이 달라질 수 있기 때문에, 구현 전에 기준을 맞추는 과정이 중요했다.
이를 통해 단순히 데이터를 적재하는 것이 아니라, 실제 운영자가 신뢰하고 사용할 수 있는 기준으로 리포트를 구성하려고 했다.

3. 설계 판단: 대용량 로그 부하를 줄이기 위한 Fact 테이블 분리
리포트 데이터의 원천은 실시간 대용량 로그였지만, 대용량 로그를 리포트에서 직접 조회하는 방식은 적합하지 않다고 판단했다.
조회 요청이 반복될수록 원천 시스템에 부하가 커지고, 리포트 응답 속도와 안정성에도 영향을 줄 수 있기 때문이다.
이를 해결하기 위해 리포트에 필요한 기준과 지표만 선별해 전용 Fact 테이블을 별도로 구성했다.
원천 로그를 매번 조회하지 않고, 분석 목적에 맞게 가공된 테이블을 조회하도록 중간 계층을 둔 것이다.
활성 구독 유저 데이터도 별도 테이블로 분리했다.
유저 구독 마트 테이블 (SCD Type2) 은 반복적으로 활용되는 데이터였고, 활성 구독 여부는 여러 리포트나 조건에서 재사용될 가능성이 높았다.
매번 동일한 조건을 쿼리 안에서 계산하기보다, 재사용 가능한 테이블로 관리하는 편이 더 효율적이라고 판단했다.
결과적으로 핵심 판단은 원천 데이터를 그대로 조회하지 않는 것이었다.
리포트 목적에 맞는 Fact 테이블과 재사용 가능한 활성 구독 테이블을 분리해, 조회 안정성과 유지보수성을 함께 확보하는 구조로 설계했다.
4. 구현 과정: 이해하고 관리하기 쉬운 구조로 정리하기
구현 과정에서는 단순히 기존 쿼리를 옮기는 데 그치지 않았다.
운영자가 구조를 쉽게 이해하고, 필요한 부분을 재사용할 수 있도록 정리하는 데 중점을 두었다.
먼저 기존 쿼리에 남아 있던 불필요한 레거시 조건을 제거했다.
더 이상 사용하지 않는 조건과 중복 로직은 쿼리 해석을 어렵게 만들고, 수정 시 영향 범위를 파악하는 데도 부담이 되기 때문이다.
복잡하게 구성되어 있던 쿼리는 임시 테이블로 분리했다.
반복적으로 사용되는 중간 결과를 테이블화해 쿼리 재사용성을 높였고, 처리 흐름도 단계별로 확인할 수 있도록 했다.
테이블명도 일관성 있게 정리했다.
Tiara 태깅 요청서를 참고해 데이터의 의미가 이름에 드러나도록 구성했고,
Action Type 기준에 따라 방문·페이지뷰 성격은 visit, 클릭·이벤트 전이 성격은 event로 구분했다.
이 과정은 혼자 결정하지 않고 사수분과 기준을 맞추며 진행했다.
약 2시간 동안 테이블명과 컬럼명을 함께 검토하면서, 명명 규칙이 단순한 컨벤션이 아니라 유지보수성과 직결되는 설계 요소라는 점을 배웠다.
(이 과정에서 많은 도움을 주신 사수분께 감사드린다. 🙇♀️)
운영 방식도 수동 실행에서 일별 배치 구조로 전환했다.
기존에는 2회 수동 실행이 필요했지만, 개선 후에는 파티션 생성, 일별 적재, 필터 적용을 통해 각 리포트가 자동으로 표현되도록 구성했다.

5. 결과: 보안, 활용성, 유지보수성 개선
개선 후 리포트는 단순 조회 화면을 넘어, 운영 관점에서 관리 가능한 구조로 전환되었다.
먼저 데이터 접근 권한을 기준으로 리포트를 관리할 수 있게 되면서, 기존 HTML 리포트에서 발생할 수 있던 보안 리스크를 줄였다.
사용자나 조직 단위로 접근 범위를 통제할 수 있어 운영 안정성도 함께 개선되었다.
일자 기준으로 데이터를 적재하면서 과거 이력 조회도 가능해졌다.
기존에는 특정 시점의 결과를 다시 확인하기 어려웠지만, 개선 후에는 기간별 추이 확인과 과거 데이터 비교가 가능해져 데이터 활용성이 높아졌다.
운영 방식은 수동 실행에서 일별 배치 기반 자동화 구조로 전환했다. (Airflow)
기존에 2회 수동으로 실행하던 작업을 자동화해 실행 누락 가능성을 줄이고, 리포트 결과의 일관성을 확보했다.
마지막으로 파트/유닛 단위로 리포트를 관리할 수 있는 구조를 마련했다.
공통 테이블과 필터 기준을 활용해 리포트별 중복 관리 비용을 줄였고, 향후 리포트 추가나 조건 변경에도 더 유연하게 대응할 수 있게 되었다.
6. 회고: 리포트 개선은 데이터 구조를 설계하는 일이었다
이번 업무는 단순히 노후 리포트를 교체하는 작업이 아니었다.
리포트에 필요한 데이터를 어떻게 생성하고 운영할지 다시 설계하는 작업에 가까웠다.
기존 쿼리를 정리하는 것만으로는 충분하지 않았다.
지표 기준, 조회 성능, 권한, 이력 관리, 배치 자동화까지 함께 고려해야 안정적으로 운영할 수 있다고 판단했다.
특히 대용량 로그를 직접 조회하는 방식은 초기 구현은 단순하지만, 장기적으로는 조회 부하와 응답 불안정 문제가 반복될 수 있었다.
그래서 리포트 목적에 맞게 Fact 테이블을 분리했다.
테이블명, 컬럼명, 집계 기준이 명확해야 후속 작업자가 데이터를 이해하고 안전하게 수정할 수 있다는 점도 체감했다.
데이터의 의미가 구조에 드러날수록 지표 추가나 조건 변경에도 대응하기 쉬워진다.
이번 경험을 통해 리포트 개선은 화면이나 SQL 수정으로 끝나는 일이 아니라는 점을 배웠다.
신뢰할 수 있는 데이터를 지속적으로 제공하기 위해서는 데이터 생성, 조회 성능, 검증 가능성, 유지보수성, 운영 자동화까지 함께 고려해야 한다.
앞으로 분석용 데이터를 설계할 때도 빠른 구현에만 집중하지 않고, 안정적으로 운영될 수 있는 구조인지 함께 보려고 한다.
'3. Data Engineering > ㅤ📘 데이터 웨어하우스' 카테고리의 다른 글
| 데이터 정합성 검증 방법 (0) | 2026.03.08 |
|---|---|
| SCD(Slowly Changing Dimensions) 개념 (0) | 2026.03.08 |
| iceberg , 아이스버그 개념 및 아키텍처 (0) | 2026.02.28 |
| [Parquet 공식문서] 파케이 개념 및 아키텍처 (0) | 2026.02.28 |
| Airflow, 에어플로우의 기본 개념 (0) | 2026.02.25 |