데이터베이스 정규화

urur-27·2025년 11월 28일

잡다한

목록 보기
15/17

데이터베이스 정규화 이해하기 (1NF ~ 3NF 정리)

데이터베이스 설계의 기본이 되는 개념이 정규화(Normalization)이다.
정규화는 데이터 중복을 줄이고, 이상 현상을 방지하며, 데이터의 일관성과 무결성을 유지하기 위한 테이블 구조 설계 원칙이다.

이 글에서는 1NF → 2NF → 3NF를 직관적인 도식으로 설명하고, 마지막에는 정규화를 언제 하지 않는지(비정규화)까지 정리한다.


1. 제1정규형 (1NF) — 원자값(Atomic Value)

1NF는 “각 컬럼의 값이 쪼갤 수 없는 단일 값이어야 한다”는 규칙이다.

❌ 1NF 위반 예시

학생ID | 이름  | 전화번호
-----------------------------
1      | 민식  | 010-1234-1234, 010-9999-8888

한 셀에 여러 값이 들어가 있으므로 1NF 위반이다.


✔ 올바른 1NF 구조

학생ID | 이름  | 전화번호
-----------------------------
1      | 민식  | 010-1234-1234
1      | 민식  | 010-9999-8888

각 셀은 단일 값(원자값)만 가진다.


2. 제2정규형 (2NF) — 부분 종속 제거 (복합키 문제 해결)

2NF는 복합키(Composite Key)에서 발생하는 부분 종속을 제거하는 것이다.
즉, 기본키 전체가 아니라 “일부 PK에만 종속되는 컬럼”이 있으면 위반이다.

❌ 2NF 위반 예시

PK = (학생ID, 과목ID)

학생ID | 과목ID | 학생이름 | 과목명 | 성적
-----------------------------------------------
1      | 101    | 민식      | 알고리즘 | A
1      | 102    | 민식      | 운영체제 | B
2      | 101    | 영희      | 알고리즘 | B
  • 학생이름 → 학생ID에만 종속됨
  • 과목명 → 과목ID에만 종속됨
    → 복합키 전체가 아니라 일부에만 종속되므로 2NF 위반

✔ 정규화된 2NF 구조

학생 테이블

students
-------------------------
학생ID(PK) | 학생이름
1          | 민식
2          | 영희

과목 테이블

courses
-------------------------
과목ID(PK) | 과목명
101        | 알고리즘
102        | 운영체제

수강 테이블

enrollment
--------------------------------------------
학생ID(PK, FK) | 과목ID(PK, FK) | 성적
1              | 101            | A
1              | 102            | B
2              | 101            | B

3. 제3정규형 (3NF) — 이행적 종속 제거 (Transitive Dependency)

3NF는 일반 컬럼이 다른 일반 컬럼을 결정하는 것을 금지한다.

❌ 3NF 위반 예시

학생ID(PK) | 학과ID | 학과명
-----------------------------
1          | CS     | 컴퓨터공학과
2          | DS     | 데이터사이언스학과

문제:

  • 학생ID → 학과ID → 학과명
  • PK가 아닌 컬럼(학과ID)이 다른 일반 컬럼(학과명)을 결정
    이행적 종속, 3NF 위반

✔ 정규화된 3NF 구조

학과 테이블

departments
----------------------------
학과ID(PK) | 학과명
CS         | 컴퓨터공학과
DS         | 데이터사이언스학과

학생 테이블

students
----------------------------
학생ID(PK) | 학과ID(FK)
1          | CS
2          | DS

정규화 요약 (1NF → 2NF → 3NF)

=================== 1NF ===================
한 셀에 여러 값 → 안됨  
각 셀은 단일 원자값으로 구성해야 함

=================== 2NF ===================
복합키 일부에만 종속된 컬럼 제거  
학생이름·과목명처럼 부분 종속 발생 시 분리

=================== 3NF ===================
일반 컬럼이 일반 컬럼을 결정하면 안 됨  
학과ID → 학과명 같은 이행적 종속 제거

🟥 정규화를 언제 하지 않을까? (비정규화)

정규화는 데이터 무결성을 높이는 장점이 있지만, 모든 상황에서 최선은 아니다.
다음 경우에는 의도적으로 정규화를 하지 않기도 한다.


✔ 1) 조회 성능(속도)이 더 중요할 때

JOIN이 너무 많아지면 조회 성능이 떨어진다.
API 서버에서는 성능을 위해 일부 칼럼을 중복 저장하기도 한다.

예) 주문 테이블에 user_name을 중복 저장  
    → JOIN 없이 바로 조회 가능

✔ 2) 분석/통계용 데이터 (OLAP)

데이터 웨어하우스나 로그 분석 시스템은 조회 집중형이라
중복이 있어도 무관하다.


✔ 3) 캐시나 검색 엔진용 데이터

Redis, Elasticsearch처럼 한 번에 덩어리로 불러오는 시스템은
정규화를 하지 않는다.


✔ 4) 비즈니스적으로 "당시 상태 그대로" 보존해야 하는 데이터

상품 가격, 이벤트명 등은 시간이 지나도 원본값을 그대로 보관해야 한다.
이 경우 중복 저장이 필요하다.


마무리

정규화는 데이터 무결성을 지키는 핵심 원칙이지만,
상황에 따라 “정규화를 하지 않는 것(비정규화)”이 성능적으로 더 나을 수 있다.

  • 1NF → 원자값
  • 2NF → 복합키 부분 종속 제거
  • 3NF → 이행적 종속 제거
profile
끄아악

0개의 댓글