> For the complete documentation index, see [llms.txt](https://krjaeh0.gitbook.io/j-log/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://krjaeh0.gitbook.io/j-log/database/design/databasenormalization.md).

# DatabaseNormalization

## **정규화(Normalization)란?**

* **데이터베이스에서 데이터의 중복을 최소화하고, 데이터 무결성을 유지하기 위한 과정**
* 테이블을 작은 단위로 분해하여 중복을 제거하고, 이상(Anomaly)을 방지하는 것이 핵심 목표

### **정규화를 해야 하는 이유**

1. **데이터 중복 감소** → 스토리지 낭비 방지
2. **데이터 무결성 유지** → 불필요한 데이터 수정 방지
3. **이상(Anomaly) 방지**
   * **삽입 이상(Insertion Anomaly)**: 특정 데이터를 삽입할 때 불필요한 데이터를 함께 입력해야 하는 문제
   * **삭제 이상(Deletion Anomaly)**: 하나의 데이터를 삭제할 때 관련 없는 데이터까지 함께 삭제되는 문제
   * **갱신 이상(Update Anomaly)**: 중복된 데이터를 수정할 때 모든 행을 수정해야 하는 문제
4. **데이터 구조 최적화** → 데이터 검색 성능 향상

***

### **정규화 과정(정규형)**

정규화는 여러 단계로 이루어져 있으며, 각 단계에서 특정 조건을 충족해야 합니다. 아래 단계별로 조건과 예시를 정리합니다.

{% stepper %}
{% step %}

### 제1 정규형(1NF) – 컬럼에 원자값(Atomic Value) 저장

📌 조건

* 모든 컬럼이 원자값(Atomic Value)을 가져야 함 (더 이상 나눌 수 없는 단일 값).
* 반복되는 속성(Repeating Group) 제거.

🔹 정규화 전 (1NF 위반)

| 학생ID | 이름  | 전화번호                         |
| ---- | --- | ---------------------------- |
| 101  | 홍길동 | 010-1234-5678, 010-5678-1234 |
| 102  | 김철수 | 010-7777-8888                |

* 전화번호 컬럼에 **두 개의 값(Atomic Value 위반)** 이 들어감.

🔹 정규화 후 (1NF 적용)

| 학생ID | 이름  | 전화번호          |
| ---- | --- | ------------- |
| 101  | 홍길동 | 010-1234-5678 |
| 101  | 홍길동 | 010-5678-1234 |
| 102  | 김철수 | 010-7777-8888 |

* **중복 데이터가 생길 수 있지만, 원자값만 저장됨**.
  {% endstep %}

{% step %}

### 제2 정규형(2NF) – 부분 함수 종속 제거

📌 조건

* 1NF를 만족해야 함.
* 부분 함수 종속(Partial Dependency) 제거 → 기본 키(Primary Key)의 일부 속성에만 의존하는 속성 제거.

🔹 정규화 전 (2NF 위반)

| 학생ID | 강의ID |     |        |
| ---- | ---- | --- | ------ |
| 101  | C001 | 홍길동 | 데이터베이스 |
| 102  | C002 | 김철수 | 운영체제   |
| 101  | C002 | 홍길동 | 운영체제   |

* **학생이름**은 학생ID에만 의존(부분 함수 종속).
* **강의명**은 강의ID에만 의존(부분 함수 종속).

🔹 정규화 후 (2NF 적용)

🔹 학생 테이블

<table data-full-width="false"><thead><tr><th>학생ID</th><th>학생이름</th></tr></thead><tbody><tr><td>101</td><td>홍길동</td></tr><tr><td>102</td><td>김철수</td></tr></tbody></table>

🔹 강의 테이블

| 강의ID | 강의명    |
| ---- | ------ |
| C001 | 데이터베이스 |
| C002 | 운영체제   |

🔹 수강 테이블

| 학생ID | 강의ID |
| ---- | ---- |
| 101  | C001 |
| 102  | C002 |
| 101  | C002 |

* **모든 속성이 기본 키(학생ID + 강의ID)에 완전 종속됨**.
  {% endstep %}

{% step %}

### 제3 정규형(3NF) – 이행적 종속 제거

📌 조건

* 2NF를 만족해야 함.
* 이행적 종속(Transitive Dependency) 제거 → 기본 키가 아닌 속성 간 종속 관계 제거.

🔹 정규화 전 (3NF 위반)

| 학생ID | 학생이름 | 학과코드 | 학과명   |
| ---- | ---- | ---- | ----- |
| 101  | 홍길동  | CS01 | 컴퓨터공학 |
| 102  | 김철수  | EE02 | 전자공학  |

* **학과명은 학과코드에 의해 결정됨 (이행적 종속)**.

🔹 정규화 후 (3NF 적용)

🔹 학생 테이블

| 학생ID | 학생이름 | 학과코드 |
| ---- | ---- | ---- |
| 101  | 홍길동  | CS01 |
| 102  | 김철수  | EE02 |

🔹 학과 테이블

| 학과코드 | 학과명   |
| ---- | ----- |
| CS01 | 컴퓨터공학 |
| EE02 | 전자공학  |

* **학과명은 학과코드를 통해 참조하도록 수정**.
  {% endstep %}

{% step %}

### BCNF (Boyce-Codd Normal Form) – 강한 이상 제거

📌 조건

* 3NF를 만족해야 함.
* 모든 결정자가 후보 키(Candidate Key)여야 함.

🔹 정규화 전 (BCNF 위반)

| 교수ID | 강의ID | 강의실  |
| ---- | ---- | ---- |
| P001 | C001 | 101호 |
| P002 | C002 | 202호 |
| P001 | C003 | 101호 |

* **강의실은 강의ID가 아니라 교수ID에 의해 결정됨 (BCNF 위반).**

🔹 정규화 후 (BCNF 적용)

🔹 강의 테이블

| 강의ID | 강의명    | 교수ID |
| ---- | ------ | ---- |
| C001 | 데이터베이스 | P001 |
| C002 | 운영체제   | P002 |

🔹 강의실 테이블

| 교수ID          | 강의실  |
| ------------- | ---- |
| P001          | 101호 |
| P002          | 202호 |
| {% endstep %} |      |

{% step %}

### 제4 정규형(4NF) - 다치 종속(Multi-Valued Dependency) 제거

📌 조건

* BCNF를 만족해야 함.
* 다치 종속(Multi-Valued Dependency, MVD)이 존재하면 분리해야 함.

{% hint style="info" %}
다치 종속이란?

* 하나의 기본 키(Primary Key)가 두 개 이상의 독립적인 속성을 결정하는 경우 발생
* 두 개의 속성이 서로 독립적으로 키에 종속되는 경우, 이를 다치 종속이라고 한다.
  {% endhint %}

🔹 정규화 전 (4NF - 다치 종속 존재)

| 학생 ID | 동아리 | 자격증     |
| ----- | --- | ------- |
| 101   | 축구  | 정보처리기사  |
| 101   | 축구  | SQL 전문가 |
| 101   | 독서  | 정보처리기사  |
| 101   | 독서  | SQL 전문가 |

* 학생 ID는 동아리와 자격증을 각각 독립적으로 결정할 수 있다.
* **학생은 여러 개의 동아리에 가입할 수 있고, 여러 개의 자격증을 보유할 수 있다.**
* 동아리와 자격증은 서로 관계가 없지만 같은 테이블에 포함되어 있어 중복이 발생한다.

🔹 정규화 후 (4NF - 다치 종속 분리)

🔹 학생-동아리 테이블

| 학생 ID | 동아리 |
| ----- | --- |
| 101   | 축구  |
| 101   | 독서  |

🔹 학생-자격증 테이블

| 학생 ID | 자격증     |
| ----- | ------- |
| 101   | 정보처리기사  |
| 101   | SQL 전문가 |

* 동아리와 자격증이 각각 독립적인 관계로 분리된다.
* 데이터 중복이 사라지고, 저장 공간이 절약된다.
  {% endstep %}

{% step %}

### 제5 정규형(5NF) - 조인 종속(Join Dependency) 제거

📌 조건

* 4NF를 만족해야 함.
* 조인 종속(Join Dependency)이 존재하면 분리해야 함.
* 분해한 테이블을 다시 조인(Join)했을 때, 원래 데이터로 정확히 복구 가능해야 함.

{% hint style="info" %}
조인 종속(Join Dependency)이란?

* 테이블이 여러 개로 분해될 수 있고, 이 테이블들을 다시 조인할 때 데이터 손실 없이 원래 데이터를 복구할 수 있어야 함.
* 테이블을 불필요하게 결합하거나 데이터 중복을 초래하는 경우, 이를 제5 정규형(5NF)으로 해결해야 한다.
  {% endhint %}

🔹 정규화 전 (5NF 위반)

| 프로젝트 ID | 직원 ID | 부서 ID |
| ------- | ----- | ----- |
| p001    | E01   | D01   |
| p001    | E02   | D02   |
| p002    | E02   | D01   |

* 직원은 특정 부서에 속해 있으며, 프로젝트에 참여하고 있다.
* 직원과 부서의 관계, 프로젝트와 직원의 관계, 프로젝트와 부서의 관계가 독립적으로 관리되어야 하지만, 현재 하나의 테이블에 결합되어 있다.
* 데이터가 중복될 가능성이 높아지고, 데이터 무결성이 깨질 수 있다.

🔹 정규화 후 (5NF 적용)

🔹 프로젝트-직원 테이블

| 프로젝트 ID | 직원 ID |
| ------- | ----- |
| p001    | E01   |
| p001    | E02   |
| p002    | E02   |

🔹 직원-부서 테이블

| 직원 ID | 부서 ID |
| ----- | ----- |
| E01   | D01   |
| E02   | D02   |
| E02   | D01   |

🔹 프로젝트-부서 테이블

| 프로젝트 ID | 부서 ID |
| ------- | ----- |
| p001    | D01   |
| p001    | D02   |
| p002    | D01   |

* 각 관계(프로젝트-직원, 직원-부서, 프로젝트-부서)가 독립적으로 유지됨
* 불필요한 데이터 중복 제거
* 조인을 통해 데이터 손실 없이 원래 데이터로 복구 가능
  {% endstep %}
  {% endstepper %}

***

> 제1 정규형(1NF) → 제2 정규형(2NF) → 제3 정규형(3NF) → BCNF까지 진행한 후에도 \*\*다치 종속(Multi-Valued Dependency)\*\*과 \*\*조인 종속(Join Dependency)\*\*이 존재하면 \*\*제4 정규형(4NF)\*\*과 \*\*제5 정규형(5NF)\*\*을 적용해야 합니다.

***

## 정규화 1NF\~5NF 비교

<table data-full-width="false"><thead><tr><th width="100">정규형</th><th>해결 문제</th><th>예제</th></tr></thead><tbody><tr><td>1NF</td><td>컬럼에 원자값(Atomic Value)만 저장</td><td>전화번호 여러 개 저장 문제</td></tr><tr><td>2NF</td><td>부분 함수 종속 제거</td><td>강의 ID가 강의명 결정</td></tr><tr><td>3NF</td><td>이행적 종속 제거</td><td>학과코드 → 학과명 종속</td></tr><tr><td>BCNF</td><td>모든 결정자가 후보 키여야 함</td><td>강의실이 교수ID에 의해 결정됨</td></tr><tr><td>4NF</td><td>다치 종속(MVD) 제거</td><td>학생-동아리, 학생-자격증 분리</td></tr><tr><td>5NF</td><td>조인 종속(Join Dependency) 제거</td><td>프로젝트-직원-부서 관계 최적화</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://krjaeh0.gitbook.io/j-log/database/design/databasenormalization.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
