07. 비정규화 이야기

7.1. 비정규화(Denormalization)에 대한 서설(序說)

  • 비정규형 모델은 정규화를 하지 않은 모델이 아니라, 정규화를 마친 후에 비정규화를 한 모델이다.
  • 비정규화(Denormalization)는 조회 성능을 향상시키기 위해 데이터를 중복하거나 그룹핑하는 과정을 의미한다.
(주문:주문상품) (Master:Detail) (1:M)정규화 모델을 비정규화(역정규화)정규화 모델에 필요한 속성만 중복
  • 비정규형을 사용하는 유일한 목적은 조회성능을 향상시키기 위해서다.
  • 단순히 조인(Join)을 피하고자,사용의 편이를 위해 중복 속성을 사용해선 안 된다.
  • 중복된 데이터는 원천 데이터와 정합성을 맞춰야 해서 사용하기 편하지 않다.
  • 무조건 빠른 것보다는 문제가 없고 정확한 데이터를 선호하고 있다.

7.2. 비정규화 원칙

  • 최우선적으로 고려할 요소는 데이터 무결성(Integrity)이다.
  • 정규형은 필수며,성능 문제가 있을 때만 비정규형을 채택한다.
  • 중복 속성은 가능한 사용하지 않으며, 추출 속성은 일부 사용할 수 있다.

7.3. 비정규형의 단점

  • 정합성
    • 비정규화 > 데이터중복 > 정합성 훼손 > 품질저하
  • 쓰기성능 저하
    • 중복 자료 : 읽기 성능 향상
    • 정합성 일치 : 쓰기 성능 저하
  • 데이터 성격이 불명확
  • 모델 확장성 저하
    • 군더더기가 많은 비정규형을 수정하는 것은 어려워 확장성이 떨어진다.
  • 개발 어려움
    • 조인이 줄어 조회 성능 및 개발이 쉽다?
    • 중복 데이터의 정합성을 맞추기 위한 개발의 난이도가 높고
    • 유지보수시 확장성이 떨어져 시스템은 점점 누더기가 되고
    • 후회하는 시점에 정규화를 도입하려고 해도 쉽지 않다.
  • 공간차지
    • 중복 데이터의 공간 차지 > 성능 저하
  • 일부 조회성능 저하
    • 데이터를 빨리 조회하기 위해 선택한 비정규형 > 성능 저하의 원인이 될 수 있다.
    • 많은 중복 속성 > 인스턴스의 길이 증가 > 블럭의 증가

7.4. 비정규화 과정

  • 좋은 비정규형 모델이 되려면 다음과 같은 과정을 거쳐야 한다.
    • 함수종속을 적용해 정규화
    • 성능 문제 발생 요건 도출
      • 성능과 관련된 특별한 요건이 있을 때만 비정규화 수행
    • 비정규화 외에 다른 방안 검토
      • 뷰{View)를 사용해서 조인 문제를 해결할 수 있는지 검토
      • 파티션(Partition)으로 데이터를 나눠서 해결할 수 있는지 검토
      • 클러스터링(Clustering)이나 IOT(Index Oriented Table) 같은 특수 형태의 테이블을 사용해서 해결할 수 있는지 검토
      • 인덱스를 조정하거나 힌트(Hint) 등으로 해결할 수 있는지 검토
      • 그밖에 DBMS의 최신 기술을 적용해 해결할 수 있는지 검토
    • 비정규화 수행
      • 어떠한 대안도 요건을 충분히 해결할 수 없다면 다양한 종류의 비정규형을 고려
    • 정합성 구현 방안 검토

7.5. 비정규화 방법 - 역정규화

  • 역정규화(Reverse-Normalization)는 비정규화(Non-Normalization)보다 협소한 의미다.
  • 비정규화의 일부가 역정규화다.
  • 내역 성격의 주문상품 엔터티를 기준으로 마스터 성격의 데이터인 주문 엔터티를 합침으로써 역정규화를 수행
  • 하위(자식) 엔터티를 기준으로 역정규화하는 것을 롤다운 역정규화(RollDown Denormalizalion)
  • 상위(부모) 엔터티를 기준으로 역정규화하는 것을 롤업 역정규화(Roll-Up Denormalizalion)
  • 중복 데이터 발생 없음
  • 주문 상품의 갯수가 늘어나면 대처하기 어려운 유연하지 못한 모델
  • 주문상품의 갯수가 정해져 있을 때만 사용할 수 있는 모델
  • 역정규화의 중요 문제점은 주문 엔터티가 삭제된다는 것
  • 주문 엔터티를 유지하면서 일부 속성만 주문상품에 추가시키는 것(역정규형 모델(X), 중복속성을 적용한 비정규형 모델(O))

7.6. 비정규화 방법 - 엔터티 합체

  • 논리 모텔링 단계에서 데이터 정체성(성격)을 파악해 엔터티를 도출하면 엔터티가 많이 생긴다.
    • 자연히 엔터티의 조인(Join)이 많이 발생해 성능 문제가 발생할 수 있어 엔터티 합체할 필요가 있다.
  • 일대일(1:1) 관계의 엔터티를 합체하는 것은 엄밀히 비정규회는 아니다.
    • 중복 데이터를 사용한 것이 아니기 때문이다. 단지 성능 향상을 위해서 엔터티를 합치는 것이지만 넓은 의미에서 비정규화로 볼 수 있다.
  • 일대일(1:1) 관계 중에는 엔터티를 과도하게 분해한 경우가 있다.
    • 이때는 성능 문제가 없더라도 엔터티를 합체히는 것이 바람직하다.
    • 논리 모델링 단계에서 지나치게 엔터티를 분해하지 않도록 주의해야한다
  • 일대다(1:M) 관계의 모델도 합체할 수 있다.(7.5. 역정규화)
    • 도저히 해결할 수 없는 성능 이슈가 아니라면 채택하지 않는 것이 바람직하다.
    • 엔터티 간의 관계가 약결합(Loosely Coupled) 관계일 때보다는 강결합(Tightly Coupled) 관계일 때 엔터티를 합체하기 적절하다.
  • 강결합관계
    • 하위(자식) 엔터티를 조회할때 상위(부모) 엔터티의 속성도 항상 같이 조회되는 관계다.
    • 쿼리에서 항상 같이 사용되는 일대다(1:M) 관계의 엔터티
    • 일대다(1:M) 관계인 두 엔터티의 인스턴스가 동시에 생성될 때
  • 엔터티 합체는 엔터티 통합과 다르다.
    • 엔터티 합체는 조회 성능을 높이기 위한 비정규화의 한 종류지만,
    • 엔터티 통합은 모델의 확장성을 위해 엔터티를 일반화하는 것이다.

7.7. 비정규화 방법 - 엔터티 분해

  • 엔터티를 분해하는 것도 엄밀히 비정규화는 아니지만 넓은 의미에서 비정규회에 포함시킨다.
  • 엔터티를 분해하는 이유는 성능이나 관리효율성을 높이기 위해서다.
엔터티 수직 분해
  • 수직분할 이유1
    • 한 개의 데이터 블록{Block)에 중요한 인스턴스를 많이 저장할수 있기 때문이다.
    • 즉 중요하지 않은 속성을 별도의 엔터티로 분리해서 해당 엔터티에는 중요한 속성만을 많이 저장하기 위해서다.
    • 같이 조회되는 속성에 대한 I/O 감소로 성능 개선
    • 로우 체이닝(Row Chaining)이나 로우 마이그레이션(Row Migration)도 감소해 성능에 좋은 영향을 끼친다.
  • 핵심적으로 사용되는 실체 엔터티나 행위 엔터티 등의 주요 엔터티.
  • Null 값이 포함된 엔터티
  • 락(Lock) 발생 최소화
  • 긴 텍스트 사용
  • 엔터티의 전체 속성 사이즈가 기본 블록{Block) 사이즈를 초과할 때도 엔터티를 수직 분해할 필요가있다.
    • 엑세스 빈도에 따라 분할, 긴텍스트 분할 등 방법
    • 로우 체이닝(Row Chaining)이나 로우 마이그레이션(Row Migration)도 감소
  • 보안
    • 일부 속성에 대한 보안 적용시 분할 필요
엔터티 수평 분해
  • 엔터티 수평 분해 방식
    • 데이터베이스 기능인 파티션(Partition) 사용
    • 물리적 엔터티 분리(예 : 연도별 주문 테이블 별도 관리)
  • 엔터티 수직 분해와 수평분해는 중복데이터가 발생하지 않는 비정규화이다.
  • 데이터 무결성을 `저해하는 비정규화가 아니므로 필요시 적극 고려하는 것도 좋다.

7.8. 비정규화 방법 - 요약(Summary) 엔터티

  • 요약(Summary) 엔터티는 원천(Raw) 엔터티를 대상으로 합계나 집계 등 미리 계산한 데이터를 저장한 엔터티다.
  • 다른 비정규화 방법과 마찬가지로 조회 성능을 극적으로 향상시킬 수 있다.
  • 요약 엔터티의 정합성을 맞추는 방법
    • 실시간 적용
    • 특정시간에 배치 적용
  • 극적인 성능향상 효과만으로 무분별하게 많이 생성해서는 안된다.
  • 너무 많으면 정합성을 맞추기 어렵다. 요약엔터티는 원천 엔터티당 1개가 바람직

7.9. 비정규화 방법 - 추출 속성

  • 추출 속성(Derived Attribute)은 기존에 존재하는 속성의 값을 추출하여 저장한 속성을 말한다.
  • 기존 속성의 값을 더한 값, 카운트한 값, 최근 값, 이전 값, 최대 값, 최소 값, 평균한 값, 여부 값 등의 속성
  • 기존 값을 그대로 복사해서 사용하는 중복 속성(Redundant Attribute)도 추출 속성에 속한다.
    • 추출 속성이든 중복 속성이든 이미 존재하는 속성의 값을 재사용하는 것이므로 같은 개념이다.
    • 하지만 추출속성보다는 중복속성이 더 문제가되기 때문에 필지는 추출속성을 중복속성과 구별한다.
  • 추출 속성을 시용하는 목적은 미리 추출(계산)해서 보관한 값을 필요한 시점에 사용하기 위해서다.
    • 필요할 때마다 계산하지 않기 위함이다.
    • 인서트 보다 조회가 훨씬 많이 실행되므로 연산 대상 범위가 넓거나 연산이 복잡할 때 사용하면 효과적이다.
  • 추출속성은 주로 하위 엔터티의 많은 데이터로부터 추출하여 상위의 엔터티의 속성으로 가져다 놓는다.
    • 중복속성(상위의 값을 하위에 중복시키는)보다 훨씬 더 성능에 많은 영향을 미친다.
  • 기초속성처럼 변한 추출속성
    • 잔고금액과 같이 업무상 기초속성처럼 귿어버린 속성은 당연히 채택해야 한다.
    • 계좌나 계약 엔터티와 같은 마스터성 엔터티에 추출속성이 많이 존재한다.
  • 추출 속성은 원천(회원로그인) 데이터에 변화가 생길때마다 업데이트해야 한다.
추출 속성추출 관계
거래와 관련된 다른 데이터도 알 수 있다
이전값을 관리하는 속성이라 할 지라도 업무 자체가 변경업무인 경우 추출속성이 아닌 원천값일 수 있다.
  • 여부 속성은 추출 속성인지 원천 속성인지 구별 할 수 있어야 한다.
  • 선분이력에서 사용되는 종료일자 속성도 추출 속성이다.
    • 새롭게 생성되는 데이터의 시작일자에서 하루를 뺀 일자를 이전 인스턴스의 종료일자에 업데이트해야 한다.
    • 만약 이 계산이 잘못되면 선분이력을 사용할 수 없으며, 시작일자만 관리하는 것보다 나빠지게 된다.
  • 추출속성 중에는 관계 속성도 존재한다.
    • 여러 단계를 거쳐 상위 엔터티를 조인하면 성능이 저하될 수 있으므로 해당 엔터티와 직접 관계를 관리한다.
E 엔터티의 a 속성은 추출관계
계좌번호 = 년도(4)지점(3) 순번(3)
  • 주식별자 값으로 추출속성을 만들면 안된다.
  • 마찬가지로 추출속성이 주식별자에 포함돼서도 안되며, 일반속성이라도 주식별자에 포함되면 안된다.

*계좌를 개설할 당시의 시점 데이터인 계좌 엔터티의 고객명 속성은 이력 엔터티에서 가져올 수 있기 때문에 추출속성이다.

  • 추출 속성은 원천 데이터가 변경될 때마다 추출 속성 값도 업데이트 해야 하므로 데이터 정합성을 맞추기가 쉽지 않다.
  • 심각한 성능문제가 없다면 추출 속성은 사용하지 않는 것이 바람직하다.
  • 만약 추출 속성을 사용하면 원천 데이터와 값을 동일하게 유지하기 위한 대책을 마련해야 한다.
  • 어플리케이션에서 정합성을 맞추는 로직을 구현하는 것은 한계가 있어, DB의 기능인 트리거(Trigger)를 시용하기도 한다.
  • 추출 속성을 사용했을 때는 또한 데이터 품질 점검을 주기적으로 실시해야 한다.
  • 만약 정합성이 깨진 데이터가 있다면 원인을 찾아서 근본 문제를 해결해야 한다.
  • 추출 속성은 지속적으로 모니터링하는 것이 좋다.

7.10. 이전 값을 관리하는 모델을 설계하는 방법

  • "변경후고객명"이 아닌 "변경후"를 뺀 "고객명"으로 한 이유는 중복속성임을 명확히 하기 위함
  • 그림 7.42 모델은 변경된 값과 그 이전 값을 같은 인스턴스에서 관리하기 때문에 이전 값에 대한 조회가 수월하다.
    • 두 개의 인스턴스를 조회해서 이전 값을찾지 않아도 된다.
  • 그림 7.42 모델은 중복 속성을 사용했기 때문에 바람직하지 않다. 성능관련된 특별한요건이 있을 때만 사용해야 한다.

7.11. 비정규화 방법 - 추출 엔터티

  • 이미 존재히는 엔터티에서 현재 유효한 인스턴스와 속성만 추출해서 관리하는 엔터티가 추출 엔터티다.

7.12. 비정규화 방법 - 반복 속성

  • 반복 속성을 사용한 엔터티는 1정규형을 위반한 엔터티다.
  • 띠라서 정규회를 검토하는 것이 우선이지만 비정규화를 할 때도 있다.
  • 반복 속성을 사용한 비정규형의 종류
    • 롤업 역정규화(Roll-Up Denormalization) 그림 7.47
    • 단순한 비정규화가 있다.
정규화 하는 게 좋다.정규화 안하는게 좋다.
  • 반복 속성 사용 VS 정구화 판단 기준
    • 반복 속성 개수의 고정 여부
    • 반복속성의 갯수가 많은 경우, 여러 속성 묶음으로 반복되는 경우
  • 반복 갯수 고정(12월)이지만 속성 묶음으로 사용되었으므로 정규화 대상이다.
  • 조회 화면의 형태( 1-Row / n-Row ) 모델 선택.
  • 정규형을 (1-Row)로 만드는 쿼리보다 비정규형을 (n-Row)로 만드는 쿼리가 더 어렵다.
  • 화변의 중요도나 빈도가 크게 차이 나지 않는다면 정규형 엔터티를 사용하는 것이 유리하다.

7.13. 비정규화 방법 - 중복 데이터

  • 모델의 변화 없이 중복 데이터 관리
    • 릴레이션1 : 과거자료만 관리
    • 릴레이션2 : 현재자료도 관리(중복, 비정규화), 때에 따라 유용하게 사용되기도 함
  • 엔터티 복사하여 중복 데이터 관리
    • 원천 엔터티에서 업무처리용으로 따로 뽑아서 저장
    • 업무 처리 오류를 대비 백업용 데이터
    • 서버가 다른 곳에서 사용하기 위한 복제 데이터
    • 같은 서버에서 조회성능 향상을 목적으로 한 복제 데이터