정규화(Normalization)란?
정규화란 중복 데이터를 허용하지 않게끔 테이블을 설계하는 방식을 의미한다.
만약 정규화가 제대로 이루어지지 않는다면, 이상현상(Abnormality)이 생길 수 있다.
또한 정규화는 5단계의 정규화까지 존재하지만, 주로 3단계의 정규화까지만 수행한다.
가장 많이 쓰이는 1NF, 2NF, 3NF, BCNF에 대해서 알아보도록 하자!
제 1 정규화(1NF)
제 1 정규화란 테이블 컬럼 당 하나의 값을 갖도록 테이블을 분해하는 것이다.
즉, 하나의 행에 컬럼의 값이 반드시 하나만 입력되도록 행을 분리하는 것을 의미한다.


[제 1 정규화 전]
주문 번호 100번인 행은 상품명과 수량 컬럼의 값을 2개씩 가지고 있기 때문에, 제 1 정규화를 진행할 수 있다.
↓
[제 1 정규화 후]
주문 번호 100번인 행의 상품명과 수량을 순서에 맞게 다른 행으로 분리하였다.
따라서 값의 개수만큼 주문 번호 행이 존재한다!
제 2 정규화(2NF)
제 2 정규화란 제 1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만들도록 테이블을 분해하는 것이다.
완전 함수 종속이란, 기본키를 구성하는 모든 컬럼들이 다른 컬럼을 결정해야 한다는 것이다.
즉 부분 함수 종속을 제거해야 한다는 의미!



[제 2 정규화 전]
주문 테이블의 기본키는 (주문 번호, 상품명)이다.
컬럼 중 고객 이름은 주문 번호에만 관련이 있어 부분 함수 종속이 발생하기 때문에, 제 2 정규화를 진행할 수 있다.
↓
[제 2 정규화 후]
따라서 주문 번호와 고객 이름을 함께하는 새로운 테이블을 생성하여, 완전 함수 종속을 만족하도록 테이블을 분리하였다.
또한 수량 컬럼은 원래 기본키에 완전히 종속되어 있기 때문에, 따로 분리하지 않아도 된다!
제 3 정규화(3NF)
제 3 정규화는 제 2 정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것이다.
이행적 종속이란 A → B, B → C의 관계가 성립할 때, A → C가 성립되는 것을 의미한다.
따라서 A → C를 (A, B)와 (B, C)로 분리하는 것이 제 3 정규화이다.



[제 3 정규화 전]
기존 테이블에서의 기본키는 (주문 번호, 상품명)이다. 하지만 상품 가격은 상품명에 의해 결정된다!!
결국 주문 번호 → 상품명 → 상품 가격이라는 이행적 종속이 발생하기 때문에, 제 3 정규화를 진행할 수 있다.
↓
[제 3 정규화 후]
이행적 종속을 제거하기 위해 상품 가격이 상품명에 직접 종속되도록 테이블을 분리하였다.
주문 번호의 상품명이 바뀌면 상품 가격도 덩달아 바뀌어야 하기 때문에, 정규화를 진행하여 번거로움을 줄일 수 있다.
BCNF(Boyce-Codd Normal Form) 정규화
BCNF 정규화는 제 3 정규화를 진행한 테이블에 대해 모든 결정자는 반드시 후보키가 되도록 테이블을 분해하는 것이다.
(결정자는 함수 종속성 A → B에서 화살표 왼쪽에 있는 A를 의미한다.)



※ 강좌 하나 당 한 명의 교수가 맡음을 가정한다.
[BCNF 정규화 전]
기존 테이블에서의 후보키는
(학생 ID, 강좌명) → 교수명
(학생 ID, 교수명) → 강좌명
이다.
이 중, 기본키를 (학생 ID, 강좌명)이라고 한다면 BCNF를 위반하는 결정자는 강좌명이 된다.
강좌명 → 교수명의 종속성이 존재하지만, 강좌명은 후보키가 아니므로 BCNF 정규화를 진행할 수 있다.
↓
[BCNF 정규화 후]
강좌명을 후보키로 만들기 위해 테이블을 분리하였다. 그 결과 강좌명 → 교수명 의 종속성이 BCNF 정규화를 만족하게 되었다!
또한 학생 ID와 강좌명, 두 개의 컬럼을 가진 테이블 역시 (학생 ID, 강좌명)의 후보키(기본키)로만 남게 된다.
데이터 모델의 독립성을 확보하기 위해서는, 데이터 중복을 제거하기 위한 정규화라는 개념이 필요하다!
하지만 과도한 정규화로 테이블을 지나치게 분해하면, JOIN 횟수가 증가하여 SELECT의 성능 저하가 발생할 수 있다.
👏
참고
'Computer Science > 데이터베이스' 카테고리의 다른 글
| [DB] 트랜잭션 락(Transaction Lock)(+ 동시성 제어) (1) | 2025.12.21 |
|---|---|
| [DB] 인덱스(Index) (0) | 2025.10.31 |
| [DB] 트랜잭션 고립 수준(Transaction Isolation Level) (0) | 2025.09.19 |
| [DB] 공통 테이블 식(CTE) (0) | 2025.09.19 |
| [DB] Union vs Union All (0) | 2025.09.10 |