데이터베이스에서 데이터의 불일치나 비효율적인 데이터 처리가 발생하는 문제를 의미하며, 주로 정규화가 부족한 관계형 데이터 모델에서 발생한다.
데이터를 삽입할 때 불필요한 데이터까지 함께 삽입해야 하는 문제
예) 과목 정보를 하나의 테이블에 저장할 때, 새로운 학생을 추가하려면 최소한 하나의 과목 정보도 필요하다면 불필요한 NULL 값이 발생할 수 있다.
동일한 데이터가 여러 곳에 중복 저장될 경우, 일부만 수정하면 데이터 불일치가 발생하는 문제
예) 학생이 수강하는 과목이 여러 개라면 학생의 연락처가 여러 개의 행에 저장될 수 있는데, 한 곳만 수정할 경우 데이터의 일관성이 깨진다.
하나의 데이터를 삭제할 때, 필요한 데이터까지 함께 삭제되는 문제
예) 학생과 수강 정보를 하나의 테이블에 저장할 경우, 특정 과목을 수강하는 마지막 학생이 삭제되면 해당 과목 정보도 함께 삭제될 위험이 있다.
데이터베이스의 한 속성이 다른 속성에 의해 결정되는 관계를 의미한다.
어떤 속성이 기본키 전체에 의해 종속될 때, 즉 기본키의 일부가 아니라 전체를 필요로 할 때 완전 함수적 종속이라고 한다.
예) (학번, 과목코드) → 성적 (성적은 학번과 과목코드 둘 다 알아야 결정됨)
기본키의 일부만으로 결정되는 종속성을 의미한다.
예) (학번, 과목코드) → 학번_이름 (이름은 학번만으로도 결정 가능)
💡 부분 함수적 종속이 존재하면 2NF가 아니다.
A → B, B → C 관계가 있을 때, A → C가 성립하는 경우
예) 학번 → 학과코드, 학과코드 → 학과명이면 학번 → 학과명도 성립한다.
💡 이행적 함수적 종속이 존재하면 3NF가 아니다.
데이터베이스에서 이상 현상을 방지하고 데이터의 중복을 최소화하기 위해 데이터를 체계적으로 분해하는 과정이다.
정규화는 여러 단계로 진행되며, 각 단계에서 특정 이상 현상을 제거한다.

비정규형 → 1NF 변환 예시
학생(학번, 이름, 수강과목)
(1, 김철수, DB, 운영체제)
위 테이블은 수강과목에 여러 개의 값(DB, 운영체제)이 포함되어 있어 1NF가 아님
학생(학번, 이름, 수강과목)
(1, 김철수, DB)
(1, 김철수, 운영체제)
따라서 이렇게 분리하면 1NF를 만족한다.
1NF → 2NF 변환 예시
학생(학번, 이름, 과목코드, 성적)
이름은 학번에만 종속되므로 학생(학번, 이름)과 성적(학번, 과목코드, 성적)으로 분리한다.
2NF → 3NF 변환 예시
학생(학번, 학과코드, 학과명)
학과명은 학과코드에 종속되므로 학과(학과코드, 학과명)로 분리한다.
3NF → BCNF 변환 예시
교수(교수ID, 강의코드, 교수명)
강의코드가 교수ID를 결정할 수 있다면, BCNF를 만족하지 않으므로 교수(교수ID, 교수명)과 강의(강의코드, 교수ID)로 분리
💡 다치 종속 (Multi-valued Dependency)
같은 테이블 내의 독립적인 두 개 이상의 컬럼이 또 다른 컬럼에 종속되는 것
즉, A → B 인 의존성에서 단일 값 A와 다중 값 B가 존재한다면 다치 종속이라고 할 수 있다. 이러한 종속을 A ↠ B 로 표기한다. (다치 종속은 이중 화살표(double arrow) ↠ 로 표기한다.)
다치 종속은 최소 2개의 컬럼이 다른 컬럼에 종속되어야 하기 때문에 최소 3개의 컬럼이 필요하다.
BCNF → 4NF 변환 예시
학생(학번, 이름, 연락처, 수강과목)
(1, 김철수, 010-1234-5678, 운영체제)
(1, 김철수, 010-8765-4321, 운영체제)
(1, 김철수, 010-1234-5678, 데이터베이스)
(1, 김철수, 010-8765-4321, 데이터베이스)
한 학생이 여러 개의 연락처와 여러 개의 수강 과목을 가질 수 있을 때, 연락처와 수강과목은 학번에 의해 결정되지만 서로 독립적이다.
즉, 학번 →→ 연락처 및 학번 →→ 수강과목의 다치 종속이 존재하게 된다.
학생_연락처(학번, 연락처)
(1, 010-1234-5678)
(1, 010-8765-4321)
학생_수강과목(학번, 수강과목)
(1, 운영체제)
(1, 데이터베이스)
이와 같이 분리하면 한 테이블에서 다치 종속이 사라지고 4NF를 만족한다.
💡 조인 종속 (Joint dependency)
하나의 릴레이션을 여러개의 릴레이션으로 분해하였다가, 다시 조인했을 때 데이터 손실이 없고 필요없는 데이터가 생기는 것
조인 종속성은 다치 종속의 개념을 더 일반화한 것이다.
4NF → 5NF 변환 예시
수강(학생ID, 강좌ID, 강사ID)
(1, A, X)
(1, B, Y)
(2, A, X)
(2, B, Y)
학생과 강좌, 강좌와 강사가 각각 독립적으로 관계를 맺고 있지만, 한 테이블로 구성되어 있다.
만약 강좌별로 다른 강사를 배정할 경우 데이터를 수정하는 과정에서 중복이 발생할 수 있다.
학생_강좌(학생ID, 강좌ID)
(1, A)
(1, B)
(2, A)
(2, B)
강좌_강사(강좌ID, 강사ID)
(A, X)
(B, Y)
이와 같이 분리하면 불필요한 중복 없이 데이터를 관리할 수 있다.
| 정규형 | 해결하는 문제 |
|---|---|
| 1NF | 모든 속성이 원자값(도메인값)을 가지도록 함 (중첩된 값 제거) |
| 2NF | 부분 함수적 종속 제거 (기본키 전체에 종속되도록) |
| 3NF | 이행적 함수적 종속 제거 (비기본키 간 종속 제거) |
| BCNF | 모든 결정자가 후보키가 되도록 조정 |
| 4NF | 다치 종속 제거 |
| 5NF | 조인 종속 제거 |
성능 최적화를 위해 정규화된 데이터를 다시 일부 중복 저장하거나 병합하는 과정이다.
정규화된 데이터
학생(학번, 이름, 학과코드)
학과(학과코드, 학과명)
반정규화된 데이터
학생(학번, 이름, 학과코드, 학과명)
학과명을 학생 테이블에 추가하여 조인을 줄여 성능을 개선
📌 참고
https://velog.io/@wisdom-one/%EC%A0%95%EA%B7%9C%ED%99%94Normalization