ERD 정규화 및 반정규화 전략

  • 데이터베이스 설계에서의 정규화 (Normalization)와 반정규화(De-normalization, 역정규화)는 데이터의 무결성과 시스템의 성능 사이에서 균형을 잡는 가장 핵심적인 두 축임
  • 두 개념은 대립하는 것이 아니라 점진적 모델링 과정에서 상호보완적으로 적용되는 전략
    • “정규화를 통해 데이터 구조를 벼리고, 반정규화를 통해 성능을 타협한다”

1. ERD 정규화 전략

  • ERD 정규화 (Normalization)
    • 데이터의 중복을 최소화하고, 무결성(Integrity)을 확보하여
    • 삽입·수정·삭제 시 발생하는 이상 현상(Anomaly)을 제거하기 위해
    • 테이블을 구조적으로 쪼개어 나가는 과정


  • 제1정규화 (1NF: 원자값 확보)
    • 개념:
      • 테이블의 모든 속성값은 더 이상 쪼개질 수 없는 원자값(Atomic Value)이어야 함
    • 현상:
      • 하나의 칸에 여러 개의 데이터가 쉼표(,) 등으로 나열되어 있으면 안됨
    • 해소 전략:
      • 중복된 그룹을 분리하여 새로운 행(Row)이나 별도의 테이블로 독립시킴
    • 예시:
      • 학생 테이블의 취미 컬럼에 ‘독서, 축구’가 동시에 들어가 있다면,
      • 이를 분리하여 다중 행으로 만들거나 학생취미 테이블을 신설할 것


  • 제2정규화 (2NF: 부분 함수 종속성 제거)
    • 개념:
      • 주식별자가 2개 이상으로 구성된 복합키(Composite Key)일 때,
      • 복합키의 일부분에만 종속되는 일반 속성이 없어야 함 (완전 함수 종속 만족)
    • 현상:
      • 복합키 중 하나에만 종속되는 속성이 있으면
      • 해당 키의 데이터가 바뀔 때 불필요한 데이터 중복과 이상 현상이 발생함
    • 해소 전략:
      • 부분 종속되는 속성과 해당 주식별자 조각을 떼어내어 별도의 테이블로 분리
    • 예시:
      • 수강신청 테이블(주식별자: 학번 + 과목코드)에 강의실명이 있다면,
      • 강의실명과목코드에만 종속되므로 과목 테이블로 뜯어내야 함


  • 제3정규화 (3NF: 이행적 함수 종속성 제거)
    • 개념:
      • 주식별자가 아닌 일반 속성들끼리 서로 종속 관계를 가지면 안됨
        • \(A \rightarrow B\) 이고 \(B \rightarrow C\) 이면 \(A \rightarrow C\) 가 성립하는 관계 제거
    • 현상:
      • 일반 속성이 다른 일반 속성을 결정하게 되면 데이터의 일관성이 깨지기 쉬움
    • 해소 전략:
      • 이행적 종속을 유발하는 일반 속성들을 모아 새로운 부모 테이블을 개설
    • 예시:
      • 사원 테이블(주식별자: 사원번호)에 부서코드부서명이 함께 있다면,
      • 사원번호부서코드를 결정하고, 부서코드부서명을 결정하는 이행적 종속이 발생함
      • 따라서 부서명부서코드와 함께 부서 테이블로 분리해야 함

2. ERD 반정규화 전략

  • ERD 반정규화 (De-normalization)
    • 정규화된 데이터 모델이 시스템의 조회(Select) 성능을 극대화하기 위해
    • 의도적으로 중복, 통합, 분리를 수행하는 엔지니어링 기법


  • 반정규화가 필요한 이유 (Triggers)
    • 정규화를 엄격하게 거치면 테이블이 수십, 수백 개로 잘게 쪼개짐
    • 이 상태에서 화면 하나에 데이터를 보여주려면 수많은 테이블을 JOIN해야 함
    • 대용량 데이터 환경이나 고속 로그 처리가 필요한 스마트팩토리 IoT 시스템, 금융 거래 시스템 등에서는 과도한 Join 비용이 시스템 마비를 초래하므로 반정규화 전략이 필수적


  • 대표적인 3대 반정규화 기법

    • 테이블 통합 및 분할 (Table Merge & Split)
      • 두 테이블 통합:
        • \(1:1\) 관계나 \(1:N\) 관계에서 Join이 너무 자주 발생해 성능이 떨어질 때,
        • 두 테이블을 하나로 합쳐 Join을 원천 차단
      • 수평 분할 (Partitioning):
        • 하나의 테이블에 대용량 데이터(예: 수억 건의 로그)가 쌓일 때,
        • 기간별(월별, 년별) 또는 지역별로 테이블을 쪼개어 검색 범위를 줄임
      • 수직 분할 (Column Split):
        • 테이블의 컬럼 중 용량이 매우 큰 텍스트(BLOB/TEXT)나 거의 조회되지 않는 보안 속성들을
        • 별도 테이블로 분리하여 디스크 I/O 효율을 높임
    • 컬럼 중복 (Column Redundancy)
      • 계산된 컬럼 추가:
        • 조회가 일어날 때마다 SUM(), AVG() 같은 집계 함수를 실시간으로 계산하면 과부하가 걸림
        • 연산 결과를 담아둘 총주문금액, 평균점수 같은 컬럼을 미리 테이블에 준비해두고 업데이트하는 방식
      • 이력 테이블 최신값 중복:
        • 수많은 변경 이력 데이터 중 ‘현재 상태’나 ‘최신 단가’를 조회하기 위해 매번 이력 테이블을 서브쿼리로 뒤지는 비용을 아끼기 위해,
        • 메인 테이블에 최신상태값 컬럼을 중복하여 보관
    • 관계 중복 (Relationship Redundancy)
      • 부모 테이블을 거쳐 조부모 테이블의 데이터를 조회하는 구조(\(A \rightarrow B \rightarrow C\))에서,
      • 중간 단계를 건너뛰고 \(A\)에서 \(C\)로 직접 갈 수 있는 외래키(FK) 선을 하나 더 연결하는 기법


  • 정규화와 반정규화의 조화 전략
    • 많은 초급 개발자들이 하는 실수
      • “처음부터 성능이 걱정되니 대충 뭉뚱그려서 테이블을 하나로 짜자”는 식의 설계를 하는 것
      • 이 경우 무결성이 깨져 데이터가 오염되는 재앙을 맞이하기 쉬움


  • 정석적인 아키텍처 가이드라인
    1. “선(先) 정규화, 후(後) 반정규화” 원칙을 고수할 것
      • 먼저 3정규화 단계까지 완벽하게 정제된 논리 ERD를 완성해야
      • 데이터의 본질적 구조와 비즈니스 규칙이 명확히 보이게 됨
    2. 반정규화는 철저히 ‘데이터 증적(로그/성능 측정 결과)’에 기반해야 함
      • 시스템 개발 단계나 실제 운영 단계에서 쿼리 성능 테스트(Explain, 응답 속도 체크)를 진행하고,
      • 성능 저하의 주범이 과도한 Join으로 밝혀졌을 때에만
      • 타겟 테이블을 지정하여 제한적으로 반정규화를 적용해야
      • 안정적인 데이터베이스를 완성할 수 있음

© 2020. AiDALab Co. All rights reserved.

Powered by Hydejack v9.2.1