정규화
정규화
뮨재 사항 제시: 하나의 거대한 테이블
| order_id | ordered_at | member_id | member_name | member_address | product_info |
|---|---|---|---|---|---|
| 1001 | 2025-08-20 | 1 | 션 | 서울시 송파구 | 10:노트북:2:1500000 15:키보드:1:50000 |
| 1002 | 2025-08-21 | 2 | 네이트 | 경기도 성남시 | 10:노트북:1:1500000 |
| 1003 | 2025-08-21 | 1 | 션 | 서울시 송파구 | 20:머우스:1:30000 |
- 갱신 이상: 만약 션 회원의 주소가 다른 주소로 변경 된다면, 션이 주문한 모든 데이터의 주소를 변경해야함
- 삽입 이상: 아직 한 번도 주문하지 않은 새로운 회원을 시스템에 등록할수 없음
- 삭제 이상: 1002번 주문 삭제 시, 네이트 고객의 유일한 주문이였다면 네이트라는 고객 자체가 사라짐
함수 종속성(Functional Dependency)
테이블에서 컬럼의 값들이 다른 컬럼의 값을 유일하게 결정하는 관계를 의미합니다.
X -> Y와 같이 표기하며 X가 Y를 함수적으로 결정한다 라고 읽습니다.
예시
member_id->member_name:member_id가1이면member_name은 항상 션이다.
제1 정규화
🌟 제1 정규화
테이블의 모든 컬럼이 원자적(Atomic)인 값만을 가져야 한다.
| order_id | member_id | member_name | product_id | product_name | product_price | order_quantity | ordered_at |
|---|---|---|---|---|---|---|---|
| 1001 | 1 | 션 | 10 | 노트북 | 1500000 | 2 | 2025-08-20 10:00:00 |
| 1001 | 1 | 션 | 15 | 키보드 | 50000 | 1 | 2025-08-20 10:00:00 |
| 1002 | 2 | 네이트 | 10 | 노트북 | 1500000 | 1 | 2025-08-21 11:00:00 |
| 1003 | 1 | 션 | 20 | 마우스 | 30000 | 1 | 2025-08-21 12:00:00 |
이제 모든 컬럼이 원자적 값을 갖게 되었습니다. 하지만 여전히 데이터 중복 문제가 남아있습니다.
1001번 주문의 션 회원 이름과 주문 날짜가 두 번이나 반복해서 저장됩니다. 이를 해결하기 위해 제2 정규형이 필요합니다.
제2 정규형
🌟 제2 정규형
- 제1 정규형을 만족해야 한다.
- 테이블의 모든 컬럼이 기본 키에 대해 완전 함수 종속 이어야 한다.
- 즉, 부분 함수 종속이 없어야 한다.
(order_id, product_id)는 복합키 입니다. 즉, 주문 ID와 상품 ID를 합쳐야 하나의 행을 고유하게 식별할 수 있습니다.
기본 키 모두에 종속되는 컬럼들
(order_id, product_id)->order_price(order_id, product_id)->order_quantity
기본 키의 일부에만 종속되는 컬럼들
order_id->member_idorder_id->member_nameorder_id->ordered_atproduct_id->product_nameproduct_id->product_price
부분 함수 종속 컬럼 테이블 분리
- orders
| order_id | member_id | member_name | ordered_at |
|---|---|---|---|
| 1001 | 1 | 션 | 2025-08-20 10:00:00 |
| 1002 | 2 | 네이트 | 2025-08-21 11:00:00 |
| 1003 | 1 | 션 | 2025-08-21 12:00:00 |
- product
| product_id | product_name | price |
|---|---|---|
| 10 | 노트북 | 1500000 |
| 15 | 키보드 | 50000 |
| 20 | 마우스 | 30000 |
- order_item
| order_id | product_id | order_price | order_quantity |
|---|---|---|---|
| 1001 | 10 | 1500000 | 2 |
| 1001 | 15 | 50000 | 1 |
| 1002 | 10 | 1500000 | 1 |
| 1003 | 20 | 30000 | 1 |
제3 정규형
🌟 제3 정규형
- 제2 정규형을 만족해야 한다.
- 이행적 함수 종속이 존재하지 않아야 한다.
기본 키가 아닌 컬럼이 다른 컬럼을 결정하는 관계를 이행적 함수 종속이라고 합니다.
- orders
| order_id | member_id | member_name | ordered_at |
|---|---|---|---|
| 1001 | 1 | 션 | 2025-08-20 10:00:00 |
| 1002 | 2 | 네이트 | 2025-08-21 11:00:00 |
| 1003 | 1 | 션 | 2025-08-21 12:00:00 |
위 테이블에서 member_name은 order_id가 아닌 member_id에 종속 됩니다.
즉, order_id -> member_id -> member_name과 같은 이행적 함수 종속 관계가 나타납니다.
이행적 함수 종속 관계 테이블 분리
- member
| member_id | member_name |
|---|---|
| 1 | 션 |
| 2 | 네이트 |
- orders
| order_id | member_id | ordered_at |
|---|---|---|
| 1001 | 1 | 2025-08-20 10:00:00 |
| 1002 | 2 | 2025-08-21 11:00:00 |
| 1003 | 1 | 2025-08-21 12:00:00 |
BCNF 정규형
🌟 BNCF(Boyce-codd Normal Form)
테이블의 모든 결정자가 후보키 여야 한다.
- 결정자: 함수 종속 관계(
X -> Y)에서X에 해당하는, 즉 다른 컬럼의 값을 결정하는 컬럼을 의미 - 후보 키: 테이블의 행을 유일하게 식별 할 수 있는 컬럼의 최소 집합
- 기본키는 여러 후보 키 중 하나를 선택한 것
수강신청 시스템 설계
- 한 학생은 여러 개의 특강을 신청할 수 있다.
- 하나의 특강은 여러 명의 교수가 가르칠 수 있다.
- 한 교수는 오직 하나의 특강만 담당한다.(이 규칙이 BCNF 위반을 만드는 핵심)
| student_id | lecture_name | professor_name |
|---|---|---|
| 101 | 데이터베이스 | 김교수 |
| 101 | 자바 | 서교수 |
| 102 | 데이터베이스 | 박교수 |
| 103 | 자바 | 서교수 |
함수 종속성 분석
(student_id, lecture_name)->professor_name학생 ID와 특강 이름을 알면 담당 교수를 알 수 있다.professor_name->lecture_name: 교수의 이름을 알면 그가 담당하는 특강 이름을 알 수 있다(규칙 3번)
후보 키 분석
(student_id, lecture_name): 모든 컬럼을 결정함므로 후보 키가 될 수 있다.(student_id, professor_name): 학생 ID와 교수 이름을 알면lecture_name도 알 수 있으므로 이 조합 역시 후보키가 될 수 있다.
여기서는 (student_id, lecture_name)을 기본 키로 선택했다고 가정합니다.
정규형 만족 여부 확인
- 제1 정규형: 모든 컬럼은 원자적 값을 가지므로 만족
- 제2 정규형
- 기본 키가 아닌 컬럼은
professor_name하나뿐 - 이 컬럼은 기본 키 전체에 종속되므로 부분 함수 종속이 없음
- 만족
- 기본 키가 아닌 컬럼은
- 제3 정규형
- 기본 키가 아닌 컬럼이 다른 기본 키가 아닌 컬럼을 결정해야 함
- 하지만 이 테이블에는 기본 키가 아닌 컬럼이
professor_name하나뿐이므로, 이행적 종속이 발생할 수 없음 - 만족
- BCNF
- 모든 결정자가 후보 키인가?
(student_id, lecture_name)는professor_name을 결정- 이 결정자는 기본 키 이므로 후보 키다.
professor_name은lecture_name을 결정professor_name만으로는 행을 유일하게 식별할 수 없기 때문에 후보 키가 아니다.- BCNF 위반
BCNF 적용하여 테이블 분리
- professor
| professor_name | lecture_name |
|---|---|
| 김교수 | 데이터베이스 |
| 박교수 | 데이터베이스 |
| 서교수 | 자바 |
- enrollment
| student_id | professor_name |
|---|---|
| 101 | 김교수 |
| 101 | 서교수 |
| 102 | 박교수 |
| 103 | 서교수 |
실무와 정규화
- 정규화는 데이터 중복 최소화, 데이터 일관성 확보, 이상 현상 해결, 유연한 구조 확보를 위해 필요
- 실무에서는 보통 제3 정규형이나 BCNF를 목표로 하지만, 조회 성능이 매우 중요한 경우
JOIN을 줄이기 위해 의도적으로 정규화를 위반하는 역정규화를 수행하기도 함 - 뛰어난 설계는 시스템의 특성에 ㅁ자게 정규화와 역정규화 사이의 최적의 균형점을 찾는 것
참고
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.