정규화란?
정규화는 데이터 중복을 최소화하고 무결성을 보장하기 위해 테이블을 분리하는 과정이다.
보통 제 1 정규형 (1NF) → 제 2 정규형 (2NF) → 제 3 정규형 (3NF) → BCNF까지 수행하며, 상황에 따라 제 4 정규형, 제 5 정규형을 적용한다.
정규화의 목적
- 데이터 중복 최소화: 중복 데이터를 최소화하여 저장 공간을 절약하고 데이터 불일치를 방지한다.
- 데이터 무결성 유지: 데이터를 변경했을 때 연관된 모든 데이터가 일관성을 유지하도록 한다.
- 데이터 구조 최적화: 테이블을 체계적으로 정리해 검색, 수정, 삭제 등의 유지보수를 쉽게 수행할 수 있다.
키의 종류
키 | 개념 | 예시 |
---|---|---|
슈퍼키 | 각 데이터를 유일하게 식별할 수 있는 속성의 집합 | student_id , student_email , (student_id, student_name) |
후보키 | 슈퍼키 중에서 최소성을 만족하는 키 | student_id , student_email |
기본키 | 후보키 중에서 대표로 선택된 유일한 키 | student_id |
대체키 | 기본키로 선택되지 않은 나머지 후보키 | student_email |
정규화 단계
각 단계에서 데이터의 문제점을 해결하며, 점점 더 효율적인 테이블 구조를 만들어간다
1. 제 1 정규형 (1NF)
모든 컬럼이 원자값(더 이상 분해할 수 없는 값)만 포함해야 한다.
즉, 하나의 컬럼에는 하나의 값만 있어야 한다.
제 1 정규형 규칙
- 각 컬럼이 하나의 속성만을 가져야 한다.
- 하나의 컬럼은 같은 종류나 타입의 값을 가져야 한다.
- 각 컬럼이 유일한 이름을 가져야 한다.
- 컬럼의 순서가 상관없어야 한다.
예시
student_id | student_name | student_email | enrolled_courses |
---|---|---|---|
S001 | 김OO | aaa@example.com | 수학, 과학, 영어 |
S002 | 이OO | bbb@example.com | 역사, 체육 |
위 테이블에서는 enrolled_courses
컬럼이 한 개의 값이 아닌 여러 개의 값을 포함하고 있다.
➡ 제 1 정규형 적용 후
student_id | student_name | student_email | course_name |
---|---|---|---|
S001 | 김OO | aaa@example.com | 수학 |
S001 | 김OO | aaa@example.com | 과학 |
S001 | 김OO | aaa@example.com | 영어 |
S002 | 이OO | bbb@example.com | 역사 |
S002 | 이OO | bbb@example.com | 체육 |
이제 한 컬럼에 하나의 값만 들어가므로 제 1 정규형을 충족한다!
2. 제 2 정규형 (2NF)
기본키의 부분 함수 종속 제거
제 2 정규형 규칙
- 제 1 정규형을 만족해야 한다.
- 기본 키가 아닌 속성 모두가 기본 키에 완전 함수 종속되어야 한다.
예시
student_id | course_id | course_name |
---|---|---|
S001 | C101 | 수학 |
S001 | C102 | 과학 |
S002 | C102 | 과학 |
S002 | C103 | 영어 |
위 테이블에서 기본키는 (student_id, course_id)
이다.
하지만 여기서 course_name
은 course_id
에 의해서도 값을 알 수 있다. -> 부분 함수 종속
➡ 2NF 적용 후 (강의 테이블 분리)
✅ 수강등록 테이블
student_id | course_id |
---|---|
S001 | C101 |
S001 | C102 |
S002 | C102 |
S002 | C103 |
✅ 강의 테이블
course_id | course_name |
---|---|
C101 | 수학 |
C102 | 과학 |
C103 | 영어 |
이제 course_name
이 course_id
에만 종속되므로 제 2 정규형을 충족한다!
3. 제 3 정규형 (3NF)
이행적 함수 종속이란, A -> B, B -> C, A -> C
일 때, A -> C
처럼 간접적으로 의존하는 관계를 말함.
즉, 속성간의 간접적 의존 관계를 제거해야 함!
제 3 정규형 규칙
- 제 2 정규형을 만족해야 한다.
- 기본키가 아닌 모든 속성 간의 간접적인 의존 관계를 없애야 한다.
예시
student_id | student_name | student_address |
---|---|---|
S001 | 김OO | 서울시 강남구 |
S001 | 김OO | 서울시 서초구 |
S002 | 이OO | 부산시 해운대구 |
여기서 student_address
는 student_name
이 아닌 student_id
에 직접 종속되어야 한다.
➡ 3NF 적용 후 (학생 주소 테이블 분리)
✅ 학생 테이블
student_id | student_name |
---|---|
S001 | 김OO |
S002 | 이OO |
✅ 학생 주소 테이블
student_id | student_address |
---|---|
S001 | 서울시 강남구 |
S001 | 서울시 서초구 |
S002 | 부산시 해운대구 |
이제 모든 컬럼이 기본키인 student_id
에 직접 종속되므로 제 3 정규형을 충족한다!
4. BCNF (Boyce-Codd Normal Form)
모든 결정자가 후보키가 되도록 분리한다.
특정 컬럼의 값이 다른 컬럼의 값을 결정하는 경우, 그 특정 컬럼을 결정자라고 한다.
예시
teacher_id | course_id | teacher_name |
---|---|---|
T001 | C101 | 김교사 |
T001 | C103 | 김교사 |
T002 | C102 | 이교사 |
위 테이블에서 기본키는 (teacher_id, course_id)
이며, 이를 통해 teacher_name
을 알 수 있다.
그러나 teacher_name
를 알면 teacher_id
를 알 수 있지만 teacher_name
은 후보키가 아니다.
즉, 후보키가 아닌 결정자가 존재하므로 BCNF를 만족하지 못한다.
➡ BCNF 적용 후 (강의-교사 테이블 분리)
✅ 교사 테이블
teacher_id | teacher_name |
---|---|
T001 | 김교사 |
T002 | 이교사 |
✅ 강의 테이블
course_id | teacher_id |
---|---|
C101 | T001 |
C102 | T002 |
C103 | T001 |
이제 모든 결정자가 후보키가 되므로 BCNF를 충족한다!
참고
'SQL' 카테고리의 다른 글
[SQL] 윈도우 함수 (0) | 2025.02.06 |
---|