“데이터 중복을 줄이고, 무결성을 지키는 가장 기본이자 중요한 설계 원칙”
데이터베이스를 설계할 때 정규화(Normalization)는
성능 최적화보다도 먼저 고려해야 할 기초 중의 기초입니다.
정규화를 제대로 이해하고 적용하면:
- 중복 데이터가 사라지고
- 삽입·갱신·삭제 이상(Anomaly) 위험이 줄며
- 스키마가 명확해져 유지보수가 쉬워집니다.
하지만 과도한 정규화는 JOIN 과다로 성능 저하를 불러오기도 하니,
“언제, 어떻게” 적용할지 균형을 잘 맞추는 게 중요합니다.
정규화란 무엇인가?
정규화(Normalization)는
관계형 데이터베이스 설계 이론 중 하나로,
테이블을 일련의 정규형(Normal Form)을 만족하도록 분해하는 과정입니다.
- 각 정규형은 테이블이 가져야 할 제약 조건을 하나씩 더 추가해 갑니다.
- 제약을 충족하지 못하면 이상(Anomaly) 발생 위험이 큽니다.
정규화를 해야 하는 이유
- 데이터 중복 최소화
- 중복된 값이 사라지면 저장 공간 절약
- 데이터 일관성(Consistency) 보장
- 갱신 이상(Updation Anomaly) 방지
- 특정 열을 수정할 때 여러 행을 수정해야 하는 번거로움 제거
- 삽입 이상(Insertion Anomaly) 방지
- 아직 완전하지 않은 데이터도 테이블에 추가할 수 있게
- 삭제 이상(Deletion Anomaly) 방지
- 일부 데이터를 삭제했을 때 다른 데이터가 의도치 않게 사라지는 현상 방지
정규화 단계(정규형) 개요
정규형 | 제약 조건 |
1NF (제1정규형) | 각 속성 값이 원자값(Atomic)이어야 한다. |
2NF (제2정규형) | 1NF + 부분 함수 종속(Primary Key의 일부 속성에만 종속) 금지. |
3NF (제3정규형) | 2NF + 이행적 함수 종속(Non-key→Non-key) 금지. |
BCNF | 3NF 강화형. 모든 결정자가 후보키여야 한다. |
4NF (제4정규형) | 다치 종속(Multi-valued Dependency) 제거. |
5NF (제5정규형) | 조인 종속(Join Dependency) 제거. |
1NF (제1정규형)
- 원자성(Atomicity) 보장: 각 컬럼은 하나의 값만 가져야 합니다.
- 반복 그룹(Repeating Group) 금지.
예시 (비정규화)
주문ID | 고객명 | 주문상품 |
1 | 김철수 | TV, 냉장고 |
2 | 이영희 | 세탁기 |
주문상품
칼럼에 복수 값이 들어가 있다 → 1NF 위반
1NF 적용 결과
CREATE TABLE Orders (
order_id INT,
customer VARCHAR(50),
product VARCHAR(50),
PRIMARY KEY(order_id, product)
);
order_id | customer | product |
1 | 김철수 | TV |
1 | 김철수 | 냉장고 |
2 | 이영희 | 세탁기 |
2NF (제2정규형)
- 1NF 조건을 만족하면서,
- 복합키(Composite Key)의 일부 속성에만 종속되는 컬럼이 없어야 합니다.
예시 (1NF만 적용)
PRIMARY KEY(order_id, product)
order_id | product | customer | product_price |
1 | TV | 김철수 | 500 |
1 | 냉장고 | 김철수 | 700 |
2 | 세탁기 | 이영희 | 300 |
product_price
는product
에만 의존 → 부분 종속. 2NF 위반customer
도order_id
만 알면 결정 가능 → 부분 종속
2NF 적용 결과
- Orders(order_id, customer)
- OrderItems(order_id, product)
- Products(product, product_price)
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer VARCHAR(50)
);
CREATE TABLE OrderItems (
order_id INT,
product VARCHAR(50),
PRIMARY KEY(order_id, product),
FOREIGN KEY(order_id) REFERENCES Orders(order_id),
FOREIGN KEY(product) REFERENCES Products(product)
);
CREATE TABLE Products (
product VARCHAR(50) PRIMARY KEY,
product_price INT
);
3NF (제3정규형)
- 2NF 조건을 만족하면서,
- 이행적 함수 종속(Transitive Dependency)이 없어야 합니다.
(Non-key → Non-key 종속 금지)
예시 (2NF만 적용)
Orders(order_id → customer, customer_address)
order_id | customer | customer_address |
1 | 김철수 | 서울시 강남구 |
2 | 이영희 | 부산시 해운대구 |
customer_address
는customer
에만 의존 → 이행적 종속. 3NF 위반
3NF 적용 결과
- Orders(order_id, customer)
- Customers(customer, customer_address)
CREATE TABLE Customers (
customer VARCHAR(50) PRIMARY KEY,
customer_address VARCHAR(100)
);
ALTER TABLE Orders
ADD FOREIGN KEY(customer) REFERENCES Customers(customer);
BCNF (보이스-코드 정규형)
- 3NF의 모든 결정자(Determiner)가 후보키(Candidate Key)여야 합니다.
예시
강사ID | 강사이름 | 과목 |
1 | 홍길동 | 수학 |
1 | 홍길동 | 물리 |
2 | 김영희 | 영어 |
{강사ID, 과목}
이 PK라면,강사이름
은강사ID
만으로 결정 → 결정자가 후보키가 아님. BCNF 위반
BCNF 적용 결과
- Instructors(instructor_id, instructor_name)
- Teachings(instructor_id, subject)
CREATE TABLE Instructors (
instructor_id INT PRIMARY KEY,
instructor_name VARCHAR(50)
);
CREATE TABLE Teachings (
instructor_id INT,
subject VARCHAR(50),
PRIMARY KEY(instructor_id, subject),
FOREIGN KEY(instructor_id) REFERENCES Instructors(instructor_id)
);
4NF, 5NF 간단 개념
- 4NF: 다치 종속(Multi-valued Dependency) 제거
- 5NF: 조인 종속(Join Dependency) 제거
- 대규모 복잡 스키마에서만 필요하며, 실무에서는 BCNF까지 적용하면 충분한 경우가 많습니다.
예제: 쇼핑몰 주문 테이블 정규화
- 비정규화 테이블
OrderInfo(order_id, customer, address, product, qty, price)
- 1NF → 2NF → 3NF → BCNF 순서로 분해
- 최종적으로 Orders, OrderItems, Customers, Products 네 개 테이블 완성
정규화 vs 비정규화: 언제 비정규화를 선택할까?
- 읽기 성능이 극히 중요하고
- 데이터 중복을 감수해도 되는 경우
예:
- 캐시 테이블
- 데이터 웨어하우스
- 통계용 집계 테이블
핵심은 “읽기 성능 ↔ 저장 공간·중복” 사이에서 균형을 찾는 것
마무리 정리
단계 | 주요 제약 조건 |
1NF | 원자성(Atomicity) |
2NF | 부분 함수 종속 제거 |
3NF | 이행적 함수 종속 제거 |
BCNF | 모든 결정자가 후보키 |
4NF | 다치 종속 제거 |
5NF | 조인 종속 제거 |
정규화는 데이터베이스 설계의 기초이며,
잘 적용하면 데이터 무결성과 유지보수성을 극대화할 수 있습니다.
728x90