데이터베이스 정규화로 중복과 이상 현상 줄이기
데이터베이스 정규화의 목적과 정규형별 분리 기준, 이상 현상 방지, 비정규화 판단 기준을 실무 관점에서 정리합니다.
2026-08-14 · 최초 발행 2025-08-10
중복된 사실은 결국 갱신 문제로 돌아온다
한 테이블에 서로 다른 관계를 함께 담으면 데이터는 쉽게 반복되고, 변경 작업은 일관성을 잃기 쉽다. 데이터베이스 정규화(Normalization)는 관계형 데이터베이스에서 이런 중복을 줄이고 무결성을 지키기 위해 릴레이션을 정규형에 맞춰 분해하는 설계 방식이다.
핵심은 함수적 종속성(Functional Dependency)이다. 어떤 속성이 다른 속성에 의해 결정되는 관계를 분석하고, 서로 독립적으로 관리해야 할 사실을 분리한다. 이 과정은 데이터 중복 제거, 갱신 이상(Anomaly) 방지, 데이터 일관성 유지를 목적으로 한다.
E.F. Codd가 1970년대에 제안한 정규화는 관계형 데이터베이스 이론의 기반을 이룬다.
삽입·삭제·수정에서 드러나는 구조적 문제
비정규화된 구조에서는 한 작업이 관계없는 데이터까지 요구하거나 소실시킬 수 있다.
삽입 이상은 새 데이터를 넣을 때 불필요한 정보까지 함께 입력해야 하는 경우다. 예를 들어 신규 과목을 개설할 때 수강 학생이 없더라도 더미 학생 정보가 필요해질 수 있다.
삭제 이상은 특정 사실을 지우면서 보존해야 할 다른 정보까지 잃는 문제다. 특정 과목의 마지막 학생 데이터를 삭제했는데 과목 정보도 함께 사라지는 상황이 여기에 해당한다.
수정 이상은 같은 정보가 여러 레코드에 중복되어 일부만 변경되는 경우다. 교수 연락처를 바꿀 때 관련된 모든 레코드를 수정해야 하므로, 누락이 발생하면 데이터가 불일치한다.
중복은 저장 공간을 낭비할 뿐 아니라 일관성 유지와 갱신 작업을 복잡하게 만든다.
종속 관계에 따라 테이블을 나누는 방식
정규화는 앞 단계의 조건을 포함하면서 진행된다. 어느 단계까지 적용할지는 데이터 간 관계와 운영 요구사항을 함께 고려해야 한다.
원자값으로 다루기 시작하는 1NF
제1정규형(1NF)은 모든 속성이 원자값(Atomic Value)만 갖도록 하는 형태다. 각 셀에는 하나의 값만 있어야 하며, 반복 그룹과 복합 속성을 분해한다.
[비정규화]
학생(학번, 이름, 수강과목[국어, 영어, 수학])
[1NF]
학생(학번, 이름, 수강과목)
복합 키의 일부에만 의존하는 값을 분리하는 2NF
제2정규형(2NF)은 1NF를 만족하면서 부분 함수적 종속성을 제거한다. 기본키가 아닌 모든 속성이 기본키 전체에 완전 함수적으로 종속되어야 한다. 키 일부에만 종속된 속성은 별도 테이블로 옮긴다.
[1NF]
수강(학번, 과목코드, 학생이름, 과목명, 성적)
[2NF]
학생(학번, 학생이름)
수강(학번, 과목코드, 성적)
과목(과목코드, 과목명)
비키 속성 사이의 종속을 끊는 3NF
제3정규형(3NF)은 2NF에 이행적 종속성 제거를 더한다. 기본키가 아닌 속성은 기본키에 비이행적으로 종속되어야 하며, 비키 속성이 다른 비키 속성을 결정하는 관계는 분리 대상이다.
[2NF]
학생(학번, 이름, 학과코드, 학과명, 학과전화)
[3NF]
학생(학번, 이름, 학과코드)
학과(학과코드, 학과명, 학과전화)
결정자가 후보키여야 하는 BCNF
BCNF(Boyce-Codd Normal Form)는 3NF를 더 엄격하게 적용한 형태다. 모든 결정자(Determinant)가 후보키(Candidate Key)여야 한다. 일반 속성이 결정자가 되는 관계가 남아 있다면 테이블을 분리한다.
[3NF]
수강신청(학번, 과목코드, 교수번호, 성적)
- 여기서 (학번, 과목코드)가 기본키이지만, 교수번호도 과목코드를 결정
[BCNF]
담당교수(과목코드, 교수번호)
수강신청(학번, 과목코드, 성적)
제4정규형(4NF)은 다치 종속성(Multi-valued Dependency)을, 제5정규형(5NF)은 조인 종속성(Join Dependency)을 제거한다. 실무에서는 대부분 BCNF까지만 적용하는 경우가 많다.
정규화가 바꾸는 데이터 관리 방식
정규화된 구조에서는 같은 사실을 여러 위치에 유지할 필요가 줄어든다. 그 결과 데이터 불일치 가능성과 갱신 이상 현상이 감소하고, 비즈니스 규칙을 데이터베이스 구조에 반영하기 쉬워진다.
테이블 간 관계가 명확해지면 새로운 데이터 유형을 추가하거나 기존 구조를 변경할 때 영향 범위를 줄일 수 있다. 더 작고 효율적인 인덱스를 구성할 수 있고, 삽입·수정·삭제 작업의 성능 향상과 질의 작성 간소화도 기대할 수 있다.
주문 데이터를 관계별로 분리한 예
초기 주문 테이블이 고객, 주문, 상품 정보를 모두 포함한다고 가정한다.
주문(주문번호, 고객ID, 고객명, 고객주소, 고객연락처, 주문일자, 상품코드, 상품명, 상품가격, 주문수량, 할인율)
이 구조는 정규형을 적용하면서 다음과 같이 관계를 분리할 수 있다.
1NF에서는 모든 속성을 원자값으로 분해한다. 이어서 2NF에서 부분 종속성을 제거하면 고객, 주문, 주문상세, 상품 정보를 분리할 수 있다.
고객(고객ID, 고객명, 고객주소, 고객연락처)
주문(주문번호, 고객ID, 주문일자)
주문상세(주문번호, 상품코드, 주문수량, 할인율)
상품(상품코드, 상품명, 상품가격)
3NF에서는 이행 종속성을 제거한다. 주소와 상품 가격 변동 이력을 독립적으로 관리할 수 있도록 구조를 나눈다.
고객(고객ID, 고객명, 고객연락처)
주소(주소ID, 상세주소)
고객주소(고객ID, 주소ID)
주문(주문번호, 고객ID, 주문일자)
주문상세(주문번호, 상품코드, 주문수량, 할인율)
상품(상품코드, 상품명, 기본가격)
가격이력(상품코드, 시작일, 종료일, 가격)
이 사례에서는 초기 설계 대비 저장 공간을 약 40% 절감했다. 고객 정보는 한 곳에서만 수정하면 되고, 상품 가격 변동 이력도 관리할 수 있다. 기간별·고객별·상품별 분석 쿼리를 작성하기에도 적합하다.
비정규화는 접근 패턴을 근거로 선택한다
정규화가 모든 시스템에서 최적의 답은 아니다. 과도한 조인으로 성능 저하가 생기거나, 데이터 웨어하우스처럼 읽기와 검색이 중심인 시스템, 복잡한 집계와 통계 처리가 필요한 보고서에서는 비정규화(Denormalization)를 검토할 수 있다.
비정규화에는 자주 조인되는 테이블을 통합하는 테이블 병합, 조인을 줄이기 위한 중복 열 추가, 계산값을 미리 보관하는 파생 데이터 저장, 수직 또는 수평 파티셔닝을 통한 테이블 분할이 있다.
정규화 수준은 시스템 요구사항에 맞춰 정한다. 트랜잭션 처리와 분석 처리의 균형을 보고, 주요 쿼리의 성능 테스트 결과를 근거로 비정규화를 적용한다.
데이터 저장 방식이 달라져도 남는 판단 기준
문서 지향 데이터베이스는 의도적인 데이터 중복을 허용하고, 그래프 데이터베이스는 관계 중심 설계로 정규화 개념을 변형한다. 컬럼 지향 데이터베이스는 수직적 분할을 통해 효율성을 추구한다.
마이크로서비스 아키텍처에서는 서비스별로 독립된 데이터베이스를 설계하고, 도메인 경계에 맞춰 정규화 범위를 제한한다. 이때도 데이터 중복과 일관성 사이에서 절충점을 찾아야 한다.
정규화는 규칙을 기계적으로 적용하는 일이 아니다. 데이터의 성격, 시스템의 목적, 성능 목표, 데이터 접근 패턴을 함께 읽고 논리적 구조를 설계하기 위한 사고 체계다.