정규화(Normalization)는 데이터베이스 설계에서 중복을 최소화하고 데이터 무결성을 유지하기 위한 체계적인 과정입니다. 관계형 데이터베이스에서 테이블을 보다 효율적이고 구조적으로 정리하기 위해 사용되며, 여러 단계(정규형, normal form)로 구분됩니다.
✅ 정규화의 목적
- 데이터 중복 최소화
- 삽입, 삭제, 갱신 이상(anomaly) 제거
- 데이터 일관성 유지
- 데이터 구조를 명확히 하여 유지보수 용이성 증가
예를 들어 아래처럼 한 테이블에 사용자와 주문 정보를 같이 저장한다고 가정해봅시다.
| user_id | user_name | order_id | product |
| 1 | alice | 101 | keyboard |
| 1 | alice | 102 | mouse |
| 2 | bob | null | null |
발생 가능한 문제:
- 중복: Alice의 정보가 여러 번 저장됨
- 삽입 이상: 주문이 없는 사용자를 추가할 때 order_id, product에 NULL을 넣어야 함
- 삭제 이상: Alice의 마지막 주문을 삭제하면 사용자 정보도 같이 사라질 수 있음
- 갱신 이상: Alice의 이름을 수정할 때 모든 행에서 수정해야 함
이런 문제를 해결하기 위해 정규화를 수행합니다.
정규화는 1NF부터 5NF까지 존재하지만, 실무에서는 보통 3NF 또는 BCNF까지 적용합니다.
🔸 제1정규형 (1NF): 원자성 (Atomicity)
- 조건: 각 컬럼은 더 이상 나눌 수 없는 원자값만 가져야 함.
- 예외 제거: 여러 개의 값을 하나의 셀에 저장하지 않음.
❌ 위반 예시
| user_id | name | phone_numbers |
| 1 | Alice | 010-1234-5678, 010-9999-8888 |
→ 전화번호 분리 필요
✅ 정규화
| user_id | name | phone_number |
| 1 | Alice | 010-1234-5678 |
| 1 | Alice | 010-9999-8888 |
🔸 제2정규형 (2NF): 부분 종속 제거
- 조건: 1NF 만족 + 기본 키가 복합키일 경우, 부분적으로 종속된 속성은 다른 테이블로 분리
- 대상: 복합 기본 키가 있는 경우
❌ 예시 (2NF 위반 테이블)
| 학번(student_id) | 과목코드(subject_code) | 학생이름(name) | 과목이름(subject_name) |
| 101 | CS101 | Alice | 컴퓨터기초 |
| 101 | MATH101 | Alice | 미적분학 |
| 102 | CS101 | Bob | 컴퓨터기초 |
- 기본 키: (student_id, subject_code) (복합 키)
- 학생이름(name)은 student_id에만 종속 → 부분 종속
- 과목이름(subject_name)은 subject_code에만 종속 → 부분 종속
✅ 정규화
Students 테이블
| student_id | name |
| 101 | Alice |
| 102 | Bob |
Enrollments 테이블
| student_id | subject_code |
| 101 | CS101 |
| 101 | MATH101 |
| 102 | CS101 |
Enrollments 테이블
| student_id | subject_code |
| 101 | CS101 |
| 101 | MATH101 |
| 102 | CS101 |
🔸 제3정규형 (3NF): 이행적 종속 제거
- 조건: 2NF 만족 + 이행적 종속 제거
- 이행적 종속: A → B, B → C → 그러면 A → C가 됨
이행성 종속에 대해 더 자세히 설명해보자면, 어떤 속성이 기본 키가 아닌 다른 속성에 종속되고, 그 속성이 다시 기본 키에 종속된 경우를 말하는 거다.
즉, A → B → C 형태로,
- A는 기본 키
- B는 일반 속성
- C는 B에 종속되어 있고
- 그러면 C는 A에 이행적으로 종속되어 있다고 합니다.
코드로 예시를 들자면,
❌ 정규화 전 (이행적 종속 있음)
| 사번(emp_id) | 직원명(name) | 부서번호(dept_id) | 부서이름(dept_name) |
| 1001 | Alice | D001 | 총무부 |
| 1002 | Bob | D002 | 개발부 |
속성 간 관계
- 기본 키: emp_id
- dept_id는 emp_id에 종속 → emp_id → dept_id
- dept_name은 dept_id에 종속 → dept_id → dept_name
- 따라서 emp_id → dept_id → dept_name → 이행적 종속 발생
👉 dept_name은 기본 키가 아닌 dept_id에 종속되었으므로, 이행적 종속
✅ 이행적 종속이 왜 문제일까?
- 중복: 부서 이름이 반복됨
- 수정 이상: 부서 이름이 바뀌면 모든 레코드 수정해야 함
- 삭제 이상: 직원이 모두 퇴사하면 부서 정보가 사라질 수 있음
✅ 3NF 정규화 결과 (이행적 종속 제거)
Employees 테이블
| emp_id | name | dept_id |
| 1001 | Alice | D001 |
| 1002 | Bob | D002 |
Departments 테이블
| dept_id | dept_name |
| D001 | 총무부 |
| D002 | 개발부 |
✅ 요약표
| 항목 | 설명 |
| 이행적 종속 | 기본 키 → 일반 속성1 → 일반 속성2 관계 |
| 제거 방법 | 속성2를 별도의 테이블로 분리 |
| 관련 정규형 | **제3정규형(3NF)**에서 제거 대상 |
| 문제점 | 데이터 중복, 이상 현상 발생 가능 |
'SQL' 카테고리의 다른 글
| 데이터베이스에서 다양한 유형의 관계 (0) | 2025.05.08 |
|---|---|
| JOIN이란? 그리고 'INNER JOIN'과 'LEFT JOIN'의 차이점 (2) | 2025.05.07 |
| 기본 키(primary key)와 외래 키(foreign key) (0) | 2025.05.01 |
| SQL 함수 (2) | 2025.01.16 |
| DDL(CREATE)+1시간 동안 오류를 못 찾은 ORA-00907: 누락된 우괄호.. (3) | 2024.12.23 |