데이터베이스 정규화 (Database Normalization)
1. 정규화란?
정규화(Normalization)는 관계형 데이터베이스에서 데이터의 중복을 최소화하고 이상현상(Anomaly)을 방지하기 위한 설계 과정이다.
이 과정은 여러 단계의 규칙(Normal Forms, NFs)을 따라 스키마를 구조화하면서 점차적으로 데이터 구조를 개선해나가는 방법이다.
정규화는 다음과 같은 문제를 해결하기 위해 수행한다:
- 삽입 이상 (Insertion Anomaly)
불완전한 데이터를 억지로 삽입해야 할 때 발생 - 삭제 이상 (Deletion Anomaly)
필요 없는 데이터를 삭제했을 때, 의도하지 않은 정보가 함께 사라지는 현상 - 갱신 이상 (Update Anomaly)
중복 데이터로 인해 하나만 변경하면 데이터 불일치가 발생할 수 있는 문제
2. 정규형(Normal Form)의 개념
정규형(Normal Form)이란 정규화가 잘 되었는지를 판단하는 규칙의 단계들이다.
보통 1NF부터 시작해, 2NF → 3NF → BCNF → 4NF → 5NF 등으로 나아간다.
실무에서는 보통 3NF 또는 BCNF까지 적용하며, 성능상 이유로 일부는 비정규화(Denormalization)로 되돌리기도 한다.
3. 핵심 용어 정리
| 용어 | 정의 |
| Prime Attribute | 후보키에 포함되는 속성 |
| Non-Prime Attribute | 후보키에 포함되지 않는 속성 |
| Functional Dependency (FD) | X → Y : 속성 X의 값이 Y 값을 유일하게 결정 |
| Fully Functional Dependency | 어떤 non-prime 속성이 전체 키에 종속되어 있고, 그 부분집합에는 종속되지 않을 때 |
| Partial Dependency | non-prime 속성이 복합 키의 일부에만 종속될 때 발생 |
| Transitive Dependency | X → Y, Y → Z 이고, Z가 X에 간접적으로 종속되는 경우 |
| Non-trivial FD | X → Y에서 Y가 X에 포함되지 않을 때 (진짜로 의미 있는 종속성) |
| Super Key | 릴레이션에서 튜플을 유일하게 식별할 수 있는 속성들의 집합 |
| Candidate Key | 최소한의 속성으로 이루어진 Super Key (중복 없는 Super Key) |

- prime 속성 = 후보키에 포함된 속성
- non-prime 속성 = 전체 속성 - 후보키
4. 각 정규형 설명 및 예시
▶ 제 1정규화 - 1NF (First Normal Form)
- 정의: 모든 속성의 값은 **원자값(Atomic value)**만을 가져야 한다. 즉, 더 이상 나눌 수 없는 단일 값이어야 한다.
- 예시 (비정규화 상태):

- 정규화 후:

▶ 제 2 정규화 - 2NF (Second Normal Form)
- 정의: 1NF를 만족하고, **모든 non-prime 속성이 전체 후보키에 대해 완전 종속(fully dependent)**이어야 한다.
→ 즉, **부분 종속(partial dependency)**이 존재하면 안 된다. - 조건: 이 규칙은 후보키가 복합 키인 경우에만 의미가 있다.
- 예시: {account_id , card_id} 복합키가 fully functionally dependent 하지 않다
즉 non-prime 속성 전체는 account_id만 있더도 되는 partial - dendency이다 - 정규화 전:

- 정규화 후:

▶제 3정규화 - 3NF (Third Normal Form)
- 정의: 2NF를 만족하고, non-prime 속성이 후보키에 대해 이행적 종속(Transitive Dependency) 되지 않아야 한다.
()X → Y이고 Y → Z일 때, X → Z는 transitive FD가 된다.
*단, 예외: Y 또는 Z 중 **하나라도 후보키의 일부(부분집합)**이면 transitive FD가 아니다.
- 예시:
-case1
empl_id -> empl_name 종속
account_id -> empl_id 종속
=> account_id - -> empl_name 종속
-case2
{bank_name,account_num} ->empl_id 종속
empl_id -> empl_name
=> {bank_name,account_num} -> empl_name 종속
위 두케이스 이행적 종속(Transitive Dependency) 발생
* 주의사항
- account_id -> class 종속
- class ->bank_name 종속
하니깐 위 케이스도 이행적 종속(Transitive Dependency) 아닌가 생각할 수 있다.
하지만!!!!! bank_name은 {bank_name , account_num} 의 일부분(부분 집합)이라 조건에 만족하지 않아. 이행적 종속이 아님!!!xxxxx
- 정규화 전:

- 정규화 후:

▶ BCNF (Boyce-Codd Normal Form)
- 정의: 모든 유효한 non-trivial FD X → Y에서 X는 반드시 Super Key여야 함.
- 차이점: 3NF보다 더 강한 조건이며, 3NF가 만족되었더라도 BCNF는 아닐 수 있음.
- 예시: class -> bank_name 종속 (은행별 등급 -> 은행을 식별)
여기서 class 는 슈퍼키가 아님!! 그래서 위반
- 정규화 전:

- 정규화 후:

5. 정규화 예외: 자동 2NF 만족
- **단일 속성 후보키(single attribute candidate key)**인 경우에는 partial dependency 자체가 존재할 수 없으므로, 자동으로 2NF를 만족한다.
- 단, 공백 FD ({} → A) 같은 경우는 예외적인 제약이 필요하다.
6. 비정규화(Denormalization)
- 정의: 성능 개선을 목적으로 의도적으로 정규화를 일부 해제하는 설계 기법.
- 이유:
- 지나치게 많은 조인 연산
- 복잡한 쿼리
- 성능 병목 현상
- 실무 시 고려사항:
- 비정규화는 읽기 성능을 향상시키지만, 쓰기 작업(Insert/Update/Delete)의 이상 현상 가능성을 높인다.
- 캐싱, 통계성 테이블, 이력 테이블 등에서 자주 사용됨.
7. 실무적 시사점
- 보통 3NF 또는 BCNF에서 멈춤: 데이터 일관성과 쿼리 복잡성 사이의 균형을 맞추기 위해.
- 이력성 데이터, 보고용 테이블 등은 정규화 예외가 많다.
- 분석 목적 데이터는 반정규화가 일반적: BI, 로그 테이블 등은 다소 중복을 허용.
8. 마무리 요약
| 정규형 | 핵심 조건 |
| 1NF | 속성 값은 반드시 원자값이어야 함 |
| 2NF | 모든 non-prime 속성은 전체 후보키에 대해 fully dependent 해야 함 |
| 3NF | 모든 non-prime 속성은 후보키에 대해 이행 종속(transitive FD)되지 않아야 함 |
| BCNF | 모든 유효한 FD에서 좌측(X)은 Super Key여야 함 |
사진 출처 - 유튜브 쉬운코드
'CS지식 > 데이터베이스 (Database)' 카테고리의 다른 글
| (데이터베이스) 파티셔닝(Partitioning),샤딩(Sharding),레플리케이션(Replication) (0) | 2025.05.29 |
|---|---|
| (데이터베이스) 인덱스(Index) 개념 정리 (Oracle 중심) (1) | 2025.05.29 |
| (데이터베이스) 트랜잭션 이상현상과 격리 수준 (SQL-92 표준 기반) (0) | 2025.05.23 |
| (데이터베이스) 설계의 기초: Functional Dependency 정리 (0) | 2025.05.23 |
| (데이터베이스) DB 스키마 설계 주의사항 (0) | 2025.05.23 |