데이터베이스 정규화: 중복과 이상 현상을 줄이는 설계 원칙

데이터베이스 정규화의 원칙과 정규형별 분리 기준, 함수적 종속성, 역정규화 판단 기준을 정리합니다.

2026-08-14 · 최초 발행 2025-08-10

데이터가 반복될 때 설계가 흔들리는 지점

정규화는 관계형 데이터베이스에서 중복 저장을 줄이고 데이터 무결성을 지키기 위한 설계 방법이다. 한 테이블에 서로 다른 관계를 함께 담아두면 변경 시 값이 어긋나거나, 필요한 정보를 삽입·삭제·갱신하기 어려운 이상 현상이 생긴다.

정규화는 이런 구조를 관계별 릴레이션으로 나누고, 데이터 일관성을 유지할 수 있도록 종속 관계를 정리하는 과정이다. 설계 과정에서는 다음 원칙을 지킨다.

  • 정규화 뒤에도 원래 정보를 복원할 수 있어야 한다. 이를 무손실 조인(Lossless-join)이라고 한다.
  • 동일한 사실을 여러 곳에 저장하는 불필요한 중복을 없앤다.
  • 독립된 관계는 독립된 릴레이션으로 표현한다.

이 원칙은 데이터 중복을 줄이는 데 그치지 않는다. 변경에 대응하기 쉬운 구조를 만들고, 불필요한 함수적 종속성을 제거하며, 데이터베이스 구조 변경의 영향 범위를 줄이는 기반이 된다.

정규형은 종속 관계를 분리하는 기준이다

1NF: 하나의 셀에는 하나의 값만 둔다

제1정규화는 원자값(Atomic Value) 원칙을 적용한다. 각 셀에는 단일 값만 있어야 하며, 반복 그룹은 별도 테이블로 분리한다.

[비정규화 상태]
고객(고객ID, 이름, 전화번호1, 전화번호2, 전화번호3)

[1NF 적용 후]
고객(고객ID, 이름)
고객전화번호(고객ID, 전화번호)

2NF: 복합키 일부에만 묶인 속성을 떼어낸다

제2정규화는 완전 함수적 종속을 다룬다. 복합키가 있는 테이블에서 일부 키에만 종속되는 속성을 분리하는 단계다.

[1NF 상태]
수강신청(학번, 과목코드, 학생이름, 과목명, 성적)
- 학생이름은 학번에만 종속
- 과목명은 과목코드에만 종속
- 성적은 (학번, 과목코드)에 종속

[2NF 적용 후]
학생(학번, 학생이름)
과목(과목코드, 과목명)
수강신청(학번, 과목코드, 성적)

학생 이름과 과목명은 수강신청이라는 관계 전체가 아니라 각각 학번과 과목코드에 의해 결정된다. 이 속성들을 분리하면 부분 함수적 종속성을 제거할 수 있다.

3NF: 키가 아닌 속성을 경유하는 종속을 없앤다

제3정규화에서는 이행적 종속을 제거한다. 기본키가 아닌 속성이 다른 비키 속성을 결정하는 구조라면 해당 관계를 별도 테이블로 옮긴다.

[2NF 상태]
학생(학번, 이름, 학과코드, 학과명, 학과전화번호)
- 학과명, 학과전화번호는 학과코드에 종속
- 학과코드는 학번에 종속 (이행적 종속)

[3NF 적용 후]
학생(학번, 이름, 학과코드)
학과(학과코드, 학과명, 학과전화번호)

BCNF: 모든 결정자를 후보키로 제한한다

보이스-코드 정규형(BCNF)은 결정자가 후보키가 아닌 경우를 처리한다. 3NF를 만족하더라도 남을 수 있는 종속성을 더 엄격하게 분리하는 방식이다.

[3NF 상태]
수강신청(학번, 과목코드, 교수번호, 성적)
- 후보키: (학번, 과목코드)
- 교수번호가 과목코드를 결정(한 과목은 한 교수만 담당)하지만 후보키가 아님

[BCNF 적용 후]
교수과목(교수번호, 과목코드)
수강신청(학번, 과목코드, 성적)

4NF: 독립적인 다중값 관계를 나눈다

제4정규화는 다중값 종속성(MVD)을 제거한다. 한 엔터티가 여러 값과 각각 독립적인 관계를 맺을 때, 이 조합으로 생기는 중복을 별도 테이블로 분리한다.

[BCNF 상태]
학생강의(학번, 수강과목, 취미)
- 한 학생이 여러 과목을 수강하고 여러 취미를 가질 수 있음
- 수강과목과 취미는 서로 독립적

[4NF 적용 후]
학생수강(학번, 수강과목)
학생취미(학번, 취미)
원자값 적용부분함수종속 제거이행함수종속 제거결정자=후보키다중값종속 제거조인종속 제거비정규화 데이터1NF2NF3NFBCNF4NF5NF

함수적 종속성을 모델에서 확인하는 방법

정규화 판단은 속성 간 함수적 종속성을 분석하는 데서 출발한다. 학생, 학과, 수강신청, 과목, 교수 관계를 분리한 예는 다음과 같다.

enrollsincludesbelongs_tobelongs_toteachestaught_bySTUDENTstringstudent_idPKstringnamestringdept_codeFKDEPARTMENTstringdept_codePKstringdept_namestringphoneENROLLMENTstringstudent_idPK,FKstringcourse_idPK,FKstringprofessor_idFKstringgradeCOURSEstringcourse_idPKstringcourse_nameintcreditsPROFESSORstringprofessor_idPKstringprofessor_namestringdept_codeFKPROFESSOR_COURSEstringprofessor_idPK,FKstringcourse_idPK,FK

정규화와 성능 사이에서 판단할 일

정규화된 구조는 저장 공간을 절약하고, 데이터 일관성을 관리하기 쉽게 하며, 변경에 따른 이상 현상을 줄인다. 반대로 테이블이 늘어나면 조인 연산이 증가하고 쿼리가 복잡해질 수 있다. 일부 상황에서는 성능 저하도 발생할 수 있다.

이때 역정규화(Denormalization)는 정규화된 구조를 의도적으로 정규화 이전 상태로 되돌리는 선택이다. 성능 향상과 복잡한 조인 감소가 목적이며, 읽기 작업이 쓰기 작업보다 훨씬 많거나 빈번한 조인으로 성능 저하가 심각한 경우, 통계 데이터 산출이 빈번한 경우에 검토할 수 있다.

정규화 수준은 업무 요구사항, 데이터 접근 패턴, 비즈니스 규칙을 함께 보고 정해야 한다. 완전한 정규화를 목표로 하기보다 필요한 수준까지만 적용하고, 성능 문제가 확인되면 선택적인 역정규화를 고려한다. ERD로 모델을 시각화하고 실제 데이터로 프로토타입을 검증하는 과정도 필요하다.

주문과 인사 데이터에서 관계를 분리하는 방식

전자상거래 시스템에서 주문 테이블에 고객정보, 상품정보, 배송정보를 모두 넣으면 서로 다른 관계가 한 테이블에 섞인다. 이를 고객, 상품, 주문, 주문상세, 배송 테이블로 분리하면 고객정보는 한 곳에서 수정해 모든 주문에 반영할 수 있고, 상품정보가 바뀌어도 주문 이력을 유지할 수 있다. 배송 상태 추적도 쉬워진다.

인사관리 시스템도 같은 방식으로 볼 수 있다. 직원 테이블에 부서정보, 직급정보, 급여이력을 함께 넣는 대신 직원, 부서, 직급, 급여이력 테이블로 나눈다. 부서 정보 변경은 해당 부서 소속 직원에게 일괄 반영할 수 있고, 직원 이동 이력을 관리하기 쉬워지며, 급여 체계 변경에도 유연하게 대응할 수 있다.

정규화를 만능 해법으로 보지 않기

모든 테이블을 5NF까지 정규화해야 하는 것은 아니다. 대부분의 경우 3NF나 BCNF까지만 적용해도 충분하다. 정규화가 언제나 성능을 높이는 것도 아니다. 조인이 과도해지면 성능이 떨어질 수 있다.

정규화와 인덱싱도 구분해야 한다. 정규화는 데이터 구조를 설계하는 일이고, 인덱싱은 성능을 최적화하는 기법이다. 기술적인 정규형만 좇다가 실제 비즈니스 규칙을 놓치면 모델은 업무 데이터를 제대로 표현하지 못한다.

데이터베이스정규화함수적 종속성BCNF역정규화