데이터 웨어하우징은 대규모 데이터의 효율적 저장과 빠른 분석을 위해 필수적인 기술입니다.
데이터 웨어하우스에서 데이터를 구조화하는 방법에는 여러 가지가 있지만, 가장 널리 알려진 두 가지는 Star Schema와 Snowflake Schema입니다.
이 포스트에서는 두 스키마의 정의와 특징을 살펴보고, 각 스키마에서 데이터 정규화가 어떻게 이루어지는지 설명합니다.
데이터베이스의 모델링과 정규화와 동시에 DW를 구축하면서 제일 많이 접하는 용어인 StarSchema, SnowFlake Schema에 대해서 정리해봤습니다.
Star Schema는 정규화를 사용하지 않는 반면, SnowFlake Schema는 정규화를 필수적으로 사용합니다.
특히 SnowFlake Schema는 정규화 (1, 2, 3) 과정을 기반으로 저장된 데이터의 중복을 없애는 것을 목표로 수행됩니다.
그럼 정확한 차이에 대한 이해를 돕기 위해서 데이터 정규화가 무엇인지, 왜 필요한지 알아보도록 하겠습니다.
정규화(Normalization)
는 데이터 설계에서 데이터를 효율적으로 저장하고 중복을 최소화하기 위해 사용되는 과정입니다.
기본 목표는, 테이블 간의 중복된 데이터를 허용하지 않는 것을 목적
으로 테이블을 분할하고 테이블 간의 관계를 정의함으로
각 테이블들의 데이터의 일관성과 무결성을 유지합니다. 이를 통해 테이블의 저장 공간을 절약하고 데이터 변경 시 발생할 수 있는 문제를 해소할 수 있습니다.
정규화는 일반적으로 1NF, 2NF, 3NF, BCNF, 4NF, 5NF 등의 단계로 나뉘는데, 단계가 올라갈수록 더 높은 수준의 데이터 무결성을 보장합니다.
위와 같이 보면 회원이름 = "김민수"
인 데이터는 헬스
뿐만 아니라, 골프 초급
이라고 하는 다른 프로그램도 수강하는 것을 확인할 수 있습니다.
보기에는 깔끔해보이지만 이런 형태로 한 컬럼에 여러 데이터를 중복해서 저장하는 경우에는 여러가지 문제가 발생합니다.
where 프로그램 = "헬스"
와 같은 where 문을 사용할 수 없다. like
문을 써야곘죠…? 따라서, 위와 같은 문제들을 해결하기 위해, 정규화가 필요합니다. 그럼 순차적으로 알아보겠습니다.
첫번째 그림에서의 김민수
라는 회원의 데이터 처럼, 하나의 테이블 컬럼에 여러개의 데이터가 중복
되어 저장하는 경우 (프로그램 컬럼)
, 해당 데이터들을 분해하는 과정입니다.
아래 그림처럼 중복
이 존재하던 테이블에서 중복
이 모두 분해된 데이터 테이블을 제 1 정규형 테이블
이라고 부르기도 합니다.
요약하면 흔하게 실무에서 보는 Join
이 필요한 (Dimenssion Table) - Partial Dependency
를 제거한 테이블입니다.
말로 풀어서 설명하면 약간 어렵게 느껴지는데, 그냥 특정 테이블에서 연관이 없는 데이터를 분리한다고 생각하면 이해하기 좋습니다.
위와 같은 테이블로 User Info Table
이 저장되어 있다는 것을 가정하면, 만약 헬스
라고 하는 프로그램의 가격
을 6000 -> 7000
으로 상향한다고 하면
보여지는 테이블에서는 단 2개의 row
만 수정하면 되겠지만, 실무에서는 몇천만개의 row
를 full scan 해야하는 비효율적 동작이 발생하게 됩니다.
그러니 위처럼, 공통되지 않은 데이터의 경우, 테이블을 분리
해서 저장하면, 각각의 테이블에 해당되는 정보만 수정하는 형태로 효율적인 데이터 관리가 가능합니다.
단일 테이블
로는 확인이 불가능하고, Join
을 통해서만 가능하게 되는 불편함이 존재하게 됩니다. 말로 풀면 어려워지는데, 간단하게 제2 정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것입니다.
2NF에서 Partial Dependency
에 해당하는 데이터들을 모두 분리해도, 위와 같이 특정 컬럼에 종속되는 데이터들이 아직 남아 있을 수 있습니다.
이 경우를 이행적 종속
이라고 하고, A->B, B->C
가 성립하면 A-C
가 성립하는 경우는 의미합니다.
가격, 강사
컬럼이 종속되고, 강사 - 출신대학으로 종속되는 데이터, 즉 강사에 이행적 종속이 발생하게 됩니다.)따라서, 위의 그림처럼 강사
컬럼을 기중으로 이행적 종속
을 테이블을 나눠서 저장하면 제 3정규형을 만족하게 됩니다.
언뜻 보면 모두 다 괜찮게 저장된 데이터처럼 보이지만 각각이 여러 Row로 구분되어 저장되어 있지 않는 구조입니다.
위의 예시의 테이블들 에서는 조회 성능 이슈와, 저장 용량에 대한 문제도 없을 것이고요, 이유는 예시로 들었던 테이블들을 모두 데이터 용량이 작기 때문입니다.
그러나, 실제 운영에서의 분석가들은 테이블로 분석 결과나 지표를 만들게 될 텐데, 당연히 작은 데이터가 아닌, 1~2년, 많으면 10년 치의 데이터를 보는 경우가 흔합니다.
결론적으론, 많은 양의 데이터에서 특정 데이터만 조회하거나, 수정하는 쿼리 를 위해서 모든 데이터를 확인해야 하는 동작이 시간적/성능적으로 엄청난 비효율이니, 이를 해소하기 위해 정규화를 진행합니다.
정규화에 대한 내용들은 워낙 많은 분들이 다루기 때문에 따로 정리하기 보다는 쉽게 설명해주시는 분의 유튜브 링크를 첨부합니다. (개인적으로 코딩 애플 팬입니다.. )
위의 사례와 같이, 각각의 비즈니스와 연관되어 있는 데이터들이 하나의 테이블에 저장되어 있는 구조를 피해가지 위해서 Star Schema를 사용합니다.
Star Schema는 DW(Data Warehouse)의 각 차원에서 Dimension Table과 Fact Table로 구성되는 일반적인 모델링입니다.
데이터를 무작정 Star Schema로 만들 거야!라고 한다면 각각의 값에 대한 정보를 기입한 Demension 테이블을 생성해야 합니다.
Dimension Table을 만들어 각각의 데이터들을 나누니 각각의 테이블이 어떤 데이터를 가지고 있는지도 명확하고, Key에 따라 어떤 값을 표현하는지도 쉽게 알 수 있습니다.
어찌 보면 당연하겠지만 Dimension은 결국 Fact와 연계되기에 Fact는 계속해서 데이터양이 늘어나지만 Dimension은 그 값이 기하급수적으로는 증가하지 않습니다.
앞으로는 Fact Table의 PK(Primart Key)
와 Dimension Table의 FK(Foreign Key)
는 서로 관계성이 있어야 되며 그것을 기반으로 서로의 테이블에 연결되는 구조입니다.
앞으로 분석가들은 전체 데이터에서의 특정 상품에 대한 데이터들의 범주를 검색하려 FACT & Dimension
을 JOIN을 사용해 필요한 데이터를 만들어서 조회하게 됩니다.
이 구조는 ERD에서 중간의 Fact 테이블을 기준으로 파생되어 있는 Dimension 테이블을 옆에 그린 뒤 관례를 연결하여 표현합니다.
저렇게 테이블의 데이터 별로 다 나눠놓고 Join으로만 쓰면 위에 말했던 저장이나, 속도 문제들은 모두 해결되는 게 아닌가요??라는 질문의 답은 = 아닙니다
단순이 테이블을 나눠 놨다고 해서 중복이나 무결성이 유지되는 것은 아닙니다. 위의 그림에서 예를 들면 제품의 가격 같은 경우는 중복이 생길 수 있는 경우죠.
이 경우 Star Schema에서 한 단계 더 나아가 Dimension으로 나누어진 테이블의 정규화까지 진행한 구조를 SnowFlake Schem
라고 합니다.
위와 같이 Product 별 데이터로 Dimension Table을 나누어서 저장해도, 채널 컬럼 데이터 속성은 제 1정규화 정책을 위반하게 됩니다. 결국 데이터의 중복이 생겨버리고 말았죠.
그렇다면 저런 형태의 데이터도 정규화를 거쳐 유일한 데이터만 가지고 있는 테이블로 만들어주는 겁니다.
이처럼 Product의 Key를 사용해, Channel에 대한 테이블들을 또 한 번 나누게 되면, 채널 별로도 유일한 데이터값을 얻을 수 있게 되죠.
이런 식으로 Star Schema로 만족되지 못한 정규화까지 진행해 데이터를 저장하면 아래와 같은 모양이 되는데, 이 모양이 눈 결정을 닮아 SnowFlake Schema
라고 합니다.
아무래도 여러 계층이 테이블로 나뉘다 보니, 끝 단 차원에 나눠져있는 데이터를 가져오는데 많은 Join이 필요하게 됩니다.
또한 계층이 많아질수록 Data Discover를 파악하기 힘들고, 복잡해집니다. 그러나 데이터 중복성이 매우 낮다는 장점
을 가지고 있습니다.
Star Schema와 Snowflake Schema는 각각의 장단점을 가지고 있고, 설계한 아키텍처나 서비스의 사용 사례에 따라 적절한 구조의 모델링을 선택하는 것이 중요합니다.
목록 구분 | Star Schema | Snowflake Schema |
---|---|---|
구조 | 중앙에 위치한 Fact 테이블과 이를 둘러싼 Dimension 테이블 | Fact 테이블과 정규화된 Dimension 테이블들로 구성 |
정규화 수준 | 최소 정규화 (일반적으로 1NF 또는 2NF) | 높은 정규화 (3NF 이상) |
쿼리 성능 | 빠른 쿼리 성능 | 상대적으로 느린 쿼리 성능 |
단순성 | 단순하고 직관적 | 복잡하고 다단계 구조 |
데이터 중복 | 데이터 중복이 있을 수 있음 | 데이터 중복 최소화 |
저장 공간 | 저장 공간 비효율적일 수 있음 | 저장 공간 효율적 |
관리 용이성 | 상대적으로 쉬운 관리 및 설계 | 상대적으로 어려운 관리 및 설계 |
사용 사례 | OLAP 시스템, 빠른 조회가 필요한 상황 | 데이터 중복 최소화가 필요한 상황, 저장 공간 최적화 필요 시 |
장점 | - 빠른 조회 성능 - 단순한 구조로 인해 이해와 관리 용이 | - 데이터 중복 최소화 - 저장 공간 효율적 사용 |
단점 | - 데이터 중복으로 인한 저장 공간 낭비 - 정규화 부족으로 인해 데이터 무결성 문제 발생 가능 | - 복잡한 구조로 인해 관리 어려움 - 조인 연산 많아 쿼리 성능 저하 가능 |