정규화의 목적은 테이블 간 중복 데이터를 최소화하는 것이었다.
제 1 정규화 부터 제 5 정규화까지 단계를 거치며 테이블을 구체적으로 분해하게 되고, 이는 테이블 간 발생할 수 있는 이상 현상들을 제거하고 무결성을 유지할 수 있게 하는 장점이 있다.
하지만 단계를 거치며 중복을 제거하기 때문에 많은 테이블로 분리가 되기 때문에 데이터를 조회하기 위해선 테이블 간 Join 연산이 늘어나 조회 성능이 낮아지는 단점이 있다.
반정규화(De-Normalizaiton)은 성능 향상, 개발 편의성 등을 위해서 정규화된 테이블 규칙을 의도적으로 위반하는 것을 의미한다.
비정규화와 반정규화?
비정규화는 정규화가 되지 않은 테이블 모델을 지칭하는 단어이고, 반정규화는 정규화 원칙을 의도적으로 위반하는 것을 의미한다.
즉, 정규화 된 테이블을 반정규화를 통해 비정규화된 테이블로 만드는 것이다..?
반정규화를 진행하는 방법에는 테이블 통합, 테이블 분할, 중복 컬럼 추가, 중복 테이블 추가 등이 있다.
테이블 통합
테이블 통합은 테이블에 지나치게 많은 Join 연산이 들어가 테이블 데이터를 조회하는데 어려움을 겪을 때 사용한다.
여러 테이블을 합침으로써 테이블 수가 줄어들고, 그로 인한 Join 연산이 줄어들게 된다.
하지만 테이블 통합으로 인해 삽입, 수정, 삭제가 복잡해지고 이상 현상이 발생할 수 있다.
테이블 통합을 하는 방법엔 1:1 관계 테이블 통합, 1:N 관계 테이블 통합, 슈퍼 타입/서브 타입 테이블 통합이 있다.
슈퍼 타입/서브 타입 테이블 통합의 경우 OneToOne, Single, Plus Type이 있는데, JPA의 상속 관계 매핑과 비슷하다.
테이블 분할
테이블 분할은 테이블 수평 분할과 테이블 수직 분할로 나뉘어진다.
테이블 수평 분할
수평 분할은 말 그대로 테이블의 수평, 즉 레코드를 기준으로 분할하는 것이다.
특정 범위의 레코드만 집중적으로 조회하는 경우 빈도에 따라 테이블을 분할한다.
이 때, 파티션이 사용된다. 파티션은 논리적으로는 하나의 테이블이지만, 여러 개의 데이터 파일에 분산되어 저장된다.
- Range Partition: 데이터 값의 범위를 기준으로 파티션을 수행한다.
- List Partition: 특정한 값을 지정하여 파티션을 수행한다.
- Hash Partition: 해시 함수를 적용하여 파티션을 수행한다.
- Composite Partition: 범위와 해시를 복합적으로 사용하여 파티션을 수행한다.
[출처 : <https://velog.io/@yewon-july/De-Normalization>]
이렇게 테이블 수평 분할을 진행하면 조회 범위가 줄어들기 때문에 성능이 향상된다.
특정 범위의 레코드만 집중적으로 조회하는 경우 기존 테이블 조회 범위보다 파티션으로 관리할 때 범위가 줄어드므로 조회 성능이 향상 될 것이다.
테이블 수직 분할
수직 분할 또한 테이블의 수직, 즉 테이블의 컬럼을 기준으로 분할하는 것이다.
- 자주 조회되는 컬럼을 기준으로 분할한다.
- 갱신이 자주 일어나는 컬럼을 기준으로 분할한다.
- 보안을 적용해야하는 컬럼을 기준으로 분할한다.
- 이미지나 텍스트와 같이 큰 데이터를 가지는 컬럼을 기준으로 분할한다.
하나의 테이블을 분할해서 사용한다면 분할된 테이블로 인한 연산 속도 성능이 저하될 수 있고, 기본키의 관리에 어려움이 있을 수 있다.
따라서, 데이터 조회에 중점을 두어 테이블 분할을 진행해야 한다.
중복 컬럼 추가
중복 컬럼을 추가하는 경우는 자주 사용되는 컬럼이 다른 테이블에 있어서 데이터 조회 범위를 줄이지 못할 때 사용한다.
다른 테이블과 조인이 자주 발생하거나 해당 컬럼에 접근하기가 까다로운 경우 테이블에 해당 컬럼을 중복적으로 추가해 사용한다.
( A라는 컬럼을 사용하기 위해 B테이블과 C테이블을 통해 조회해야하는 경우 해당 컬럼에 접근하기가 까다롭다.)
중복 컬럼을 추가하는 경우 다른 테이블의 컬럼과 중복되는 컬럼이고 실질적으로는 Join을 해서 사용해야 하는 컬럼이었기 때문에 데이터의 일관성에 유의해야한다.
또한, 중복 컬럼으로 인한 추가적인 공간을 차지하기 때문에 공간 낭비도 고려할 필요가 있다.
중복 테이블 추가
중복 테이블을 추가하는 경우는 대량의 데이터를 조회하거나, 다른 서버에 있는 테이블을 이용하는 경우 그리고 여러 테이블에서 데이터를 추출해서 사용해야 경우에 주로 사용된다.
특정 범위를 자주 조회하거나 대량의 범위를 자주 처리할 때 해당 범위를 중복 테이블로 처리한다면 조회 속도에 있어서 성능 향상을 바랄 수 있다.
- 집계 테이블 추가 : 여러 테이블의 데이터를 집계해서 사용하는 집계 데이터의 경우 각 원본 테이블에 트리거를 설정해 사용하며, 트리거 오버헤드에 유의한다.
- 진행 테이블 추가 : 이력 관리 등의 목적으로 추가하는 테이블이며, 마스터 테이블에 있는 레코드를 중복해서 저장한다. 데이터의 양을 적절하게 유지해야하며 기본키를 적절히 설정해야 한다.
- 부분 테이블 추가 : 대량의 데이터가 있는 테이블에서 특정 범위의 컬럼만 자주 사용 되는 경우 해당 컬럼들로 중복된 테이블을 구성해서 사용한다.
반정규화 시 고려 사항
반정규화를 통해 데이터의 조회의 성능적인 부분에서 강점을 가져올 수 있지만, 데이터 모델의 유연성이 낮아지고 정규화 이전의 문제였던 데이터의 중복으로 인해 이상현상이 발생할 수 있기 때문에 반정규화할 대상을 정확히 조사한 후 사용해야한다.
또한, 반정규화 이전에 View나 인덱스 튜닝, 클러스터링 같은 다양한 방법을 우선 사용할 수 있는지 판단하는 작업도 필요하다.
📄 References
반정규화와 성능 : https://dataonair.or.kr/db-tech-reference/d-guide/sql/?mod=document&uid=333
3-1-14장. 반정규화(Denormalization) - B : https://lipcoder.tistory.com/337
[데이터 모델링의 이해]반정규화(De-Normalization) : https://velog.io/@yewon-july/De-Normalization
'Computer Science > DB' 카테고리의 다른 글
SQL과 관계형 모델 (정규화) (DB 스터디 3주차) (0) | 2022.09.28 |
---|---|
술어논리와 관계형 모델 (DB 스터디 2주차) (0) | 2022.09.21 |
SQL과 관계형 모델 (DB 스터디 1주차) (0) | 2022.09.16 |
정규화 (Normalization) (0) | 2022.06.22 |
인덱스(Index) (0) | 2022.06.09 |