1. 엔터티 합체
- 일대일 관계의 엔터티가 주를 이룸
- 논리 모델링 단계에서 진행
- 엄밀히 비정규화는 아님
- 중복 데이터를 사용한 것은 아님. 단지 성능 향상을 위해서 임
CASE) 경합이 발생하지 않도록 분해한 모델
- 하나의 엔터티로 합체하면 보통 하나의 블록만을 사용하므로 성능상 유리할 수 있음
CASE) Master와 Detail의 일대다(1:M) 관계인 모델과 릴레이션
- 주문내역 엔터티를 기준으로 마스터 성격의 데이터인 주문 엔터티를 합체
- 주문내역 엔터티의 속성은 그대로 두고 주문 엔터티의 속성을 포함함 해결할 수 없는 성능 문제시만 사용
- 성능 이슈는 자주 사용되고 중요한 엔터티인 핵심적인 엔터티에서 발생함
- 일대다(1:M) 관계의 엔터티를 하위(자식) 엔터티를 기준으로 상위(부모) 엔터티를 합치는 비정규화를 할 때는 상위(부모) 엔터티의 속성 갯 수가 많은면 적당하지 않음
- 엔터티 간의 관계가 약 결합(Loosely Coulped) 관계일 때보다는 강 결합(Tightly Coupled) 관계일 때 엔터티를 합체하거나 중복 속성을 사용하는 비정규형을 채택하기 적당함
- 하위(자식) 엔터티를 조회할 때 상위(부모) 엔터티의 속성도 항상 같이 조회도면 강 결합 관계임
- 쿼리에서 항상 같이 사용되는 일대다(1:M) 관계의 엔터티가 있다면 비정규형의 채택을 고려해 볼 수 있음
- 두 엔터티의 인스턴스가 동시에 생성될 때도 비정규형을 고려해볼 수 있음
- 슈퍼타입과 서브타입의 일대일(1:1) 관계도 항상 같이 조회되는 강 결합(Tightly Coupled) 관계라면 엔터티를 합체하는 것이 효율적
2. 엔터티 분해
수직 분해: 속성의 사용 빈도를 기준으로 하거나 varchar2, LOB 등과 같은 특별한 데이터 타입의 속성을 기준으로 분해
- 일대일(1:1)분해: 하나의 엔터티를 분해하면 일대일(1:1) 관계의 두 개의 엔터티가 생김, 데이터의 성격이 다를시, 특히 실무에서 성능 이슈시
- 하나의 데이터 블록에 많은 인스턴스를 저장해 성능을 높임
- 핵심 엔터티(실체,행위)면서 속성이 많을 때, 자주 사용되는 속성과 그렇지 않은 속성을 분리
- 핵심 엔터티에서 많은 속성이 관리되며 사용도 빈번하고 성능에 민감해서 자주 사용되는 속성만으로 구성해 한 블록에 많은 데이터를 저장하면 성능 측면에서 최적이 될 수 있음
- 추후에 속성이 추가되면 핵심 엔터티를 수정하지 않고 관리. 핵심 엔터티의 변경을 최소화
- 성능적인 이슈로 락(Lock) 발생 방지를 위해. 업무적으로 같이 사용되지 않는 속성을 구분 분해. 트랜잭션에 미영향
- 조회가 주로 발생하는 속성과 업데이트가 빈번히 발생하는 속성으로 엔터티를 분해
- 긴 텍스트를 사용하는 속성 분리(varchar2(500)등). 로우 체이닝이나 로우 마이그레이션이 발생될 수 있음
- 엔터티의 전체 속성 사이즈가 기본 블록 사이즈를 초과할 때는 트랜잭션 등을 검토해 엔터티를 수직 분해 고려
- 블록에 많은 데이터를 담으면 경합(Contention)이 발생해 대기(Wait) 현상이 발생할 수 있음
수평 분해
> 엔터티의 인스턴스를 주로 기간 기준으로 분해하는 것. 파티션닝(Partitioning) 의미. 파티션은 데이터베이스에 해당하는 물리적인 요소
- 기간 등을 기준으로 엔터티에 파티션을 적용. 물리적으로 분리. 조각난 파티션 테이블은 놀리적 하나의 테이블
- 인스턴스의 데이터를 특정 기준에 따라 물리적으로 분리한 백업 엔터티를 추가하는 것. 과거 데이타 별도 테이블에 분리
3. 요약(Summary)엔터티 추가
- 중복 데이터가 되는 이유 중 가장 많은 부분을 차지하는 것이 "요약 엔터티"
- 합계나 집계 등을 미리 계산해서 저장해 놓음으로써 조회 성능을 향상시킬 수 있음
- 미리 계산해 놓은 것도 데이터를 중복해서 관리하는 방법이어서 데이터 정합성을 주의해야 함
- 원천(Raw) 데이터를 사용해서 계산(Summary)한 것이므로 원천 데이터에 수정이 발생하면 요약 엔터티도 어떤 식으로든 처리돼야 함
- 원천 데이터가 수정되는 시점에 실시간으로 요약 엔터티도 수정하는 방법과 특정 시간을 정해 배치(Batch)로 요약 엔터티의 데이터를 맞추는 방법이 있으
- 계산을 미리 수행해 저장한 요약(Summary) 엔터티와 유사한 중복 엔터티가 있음. 서버가 다를 때 원격 조인을 없애려고 엔터티를 그대로 복사해 사용할 때도 있음
(EAI(Enterprise Application Intergration) 솔루션을 통해 많이 사용) - 같은 서버에 존재하더라도 많이 조회되는 엔터티가 있다면 조회 성능을 향상시키기 위해 엔테티를 복사해 사용할 수도 있음
(메모리의 대기(Wait) 현상으로 사용)
4. 중복 속성 채택
- 이미 존재하는 속성의 값을 중복해서 사용하는 속성
- 중복 속성은 주로 상위(부모) 엔터티에 존재하는 속성을 하위(자식) 엔터티에 복사(Copy)해서 사용
- 조인(Join)하지 않을 목적으로 사용
- 가장 경계해야 할 것은 업데이트가 발생하는 중복 속성임
- 엔터티 간의 관계가 참조 관계(Referential Relationships)일 때보다는 종속 관계(Dependent Relationships)일 때 비교적 중복 속석을 채택하기 적당
- 종속 관계의 엔터티는 부모엔터티의 속성이 자식 엔터티에 존재해도 부작용이 최소화 됨
- 참조 관계일 때 상위(부모) 엔터티는 주로 실체 엔터티이고
- 하위(자식) 엔터티는 트랜잭션 테이블 데이터를 관리하는 엔터티이므로
- 인스턴스가 매우 많아 상위(부모) 엔터티의 속성을 중복 속성으로 사용하면 부작용이 더 커지게 됨
- 두 엔터티의 관계선 카디널러티가 일대일(1:1)에 가까울수록 중복 속성을 채택하면 부작용이 적어짐
- 중복 데이터를 줄이는 게 의미가 있으므로 중복해서 사용할 속성의 길이도 가능한 한 짧아야 좋음
- 그래야 데이터를 맞춰야 하는 이슈와 저장 공간이 늘어나는 부작용이 줄어듬
5. 추출 속성 채택
- 추출(Derived) 속성을 중복(Duplicated) 속성과 구별. 이미 존재하는 속성의 값을 재사용하는 것으로 같은 개념
- 보통 기존에 존재하는 속성의 값을 연산하거나 가공해 생성한 값을 관리하는 속성
- 목적은 미리 계산해 값으로 보관하고 필요한 시점에 계산하지 않기 위함
- 집계 엔터티를 사용하는 것과 유사. 필요한 값을 미리 계산해 생성했으므로 조회 시점에는 별도로 계산하지 않고 있는 값을 그대로 사용함으로 조회 성능이 향상
- 주로 하위(자식) 엔터티에서 많은 데이터를 읽어서 처리한 후의 값을 상위(부모) 엔터티의 속성으로 가져다 놓음
(Sum, Count, Min, Max, Average, Previous, Next, Firtst, Last, Flas 등) - 처리 범위가 넓을 때에 한해서 제한적으로 사용해야 함
- 대부분 데이터 정합성을 실시간으로 맞춰야 함
- 여부 속성은 가장 많이 사용되는 속성 중 하나임
- 여부 속성은 생각보다 정합성을 맞추기 어려워서 가능하면 추출 속성으로 사용하지 않는 것이 바람직
- 선분 이력에서 사용되는 종료일자 속성도 추출 속성
- 추출 속성 중에는 관계 속성도 존재함. 관계를 지속적으로 상송하면 하위(자식) 엔터티의 주 식별자에 많은 속성이 포함되므로 적당한 시점에서 관계를 단절 시켜야 함
- 관계가 적절하게 상속되거나 단절됐다면 추출 관계를 관리하지 않아도 될 수 있음
6. 반복 속성 채택
- 엔터티에 반복되는 속성이 존재하면 정규화를 해야함. 하지만 정규형을 사용해 성능 이슈가 발생할 수 있다면 비정규형을 고려
- 화면과 관련된 성능 이슈는 화면 구성이나 조회 방법 등을 바꿀 수 있는지 먼저 검토. 화면 수정이 어려우면 비정규형을 고려
- 시간이 지나면서 화면은 바뀔 가능성은 많지만 데이터는 원천적으로 프로세스나 화면에 종속되지 않으므로 정규형을 우선으로 검토해야 함
7. 중복 데이터 채택
- 모델 구조적으로는 달라지는 것이 없지만 중복 데이터를 채택하는 것도 넓은 의미에서 비정규화에 포함