Topic (오늘의 주제)
정규화(Normalization)는 데이터베이스 설계에서 데이터 중복을 최소화하고 데이터 무결성을 보장하기 위해 테이블을 분해하는 과정이다. 정규화를 통해 데이터의 일관성, 무결성, 효율성을 향상시킬 수 있다.
정규화는 왜 알아야할까?
비정규화된 테이블에서는 데이터 중복, 갱신 이상(Update Anomaly), 삽입 이상(Insert Anomaly), 삭제 이상(Delete Anomaly) 등의 문제가 발생합니다. 예를 들어, 치킨 주문 시스템에서 한 메뉴의 정보를 수정하려면 여러 행을 모두 수정해야 하고, 메뉴가 삭제되면 관련된 모든 주문 정보가 함께 삭제되는 문제가 발생할 수 있습니다.
정규화를 통해 데이터 중복을 제거하고, 각 테이블이 단일 책임을 가지도록 분리하여 데이터 무결성을 보장합니다. 이를 통해 데이터 일관성을 유지하고, 저장 공간을 절약하며, 데이터베이스 성능을 최적화할 수 있습니다.
정규화의 각 단계(1NF, 2NF, 3NF, BCNF 등)를 이해하고, 언제 정규화를 적용하고 언제 비정규화를 고려해야 하는지 판단할 수 있어야 합니다.
1. 정규화의 목적
정규화를 통해 해결하는 문제들
- 데이터 중복 제거: 같은 데이터가 여러 곳에 저장되는 것을 방지
- 데이터 무결성 보장: 데이터의 일관성과 정확성 유지
- 갱신 이상 방지: 한 곳에서만 데이터를 수정하면 모든 곳에 반영
- 삽입 이상 방지: 불필요한 데이터 없이 새로운 데이터 추가 가능
- 삭제 이상 방지: 관련 없는 데이터가 함께 삭제되는 것을 방지
2. 정규화 단계
1NF (제1정규형, First Normal Form)
정의: 각 컬럼이 원자값(Atomic Value)만을 가지도록 하는 것. 즉, 하나의 셀에는 하나의 값만 저장되어야 한다.
치킨 주문 예시 - 정규화 전:
| 주문ID | 고객번호 | 고객이름 | 메뉴번호 | 메뉴명 | 가격 | 브랜드 | 주문일시 | 배달예정시간 |
|---|---|---|---|---|---|---|---|---|
| 1 | C001 | 김철수 | M001, M002 | 후라이드치킨, 양념치킨 | 18000, 20000 | BHC, BHC | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 2 | C002 | 이영희 | M003 | 간장치킨 | 19000 | 교촌치킨 | 2024-01-15 19:30 | 2024-01-15 20:30 |
문제점:
- 한 행에 여러 메뉴 정보가 저장되어 있음 (비원자값)
- 메뉴 정보를 조회하거나 수정하기 어려움
- 데이터 중복 발생
1NF 적용 후:
| 주문ID | 고객번호 | 고객이름 | 메뉴번호 | 메뉴명 | 가격 | 브랜드 | 주문일시 | 배달예정시간 |
|---|---|---|---|---|---|---|---|---|
| 1 | C001 | 김철수 | M001 | 후라이드치킨 | 18000 | BHC | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 2 | C001 | 김철수 | M002 | 양념치킨 | 20000 | BHC | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 3 | C002 | 이영희 | M003 | 간장치킨 | 19000 | 교촌치킨 | 2024-01-15 19:30 | 2024-01-15 20:30 |
개선점:
- 각 셀에 하나의 값만 저장 (원자값)
- 메뉴별로 별도의 행으로 분리
2NF (제2정규형, Second Normal Form)
정의: 1NF를 만족하면서, 부분 함수 종속(Partial Functional Dependency)을 제거하는 것. 즉, 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속되어야 한다.
치킨 주문 예시 - 1NF 상태 (여전히 문제 있음):
| 주문ID | 고객번호 | 고객이름 | 메뉴번호 | 메뉴명 | 가격 | 브랜드 | 주문일시 | 배달예정시간 |
|---|---|---|---|---|---|---|---|---|
| 1 | C001 | 김철수 | M001 | 후라이드치킨 | 18000 | BHC | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 2 | C001 | 김철수 | M002 | 양념치킨 | 20000 | BHC | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 3 | C002 | 이영희 | M003 | 간장치킨 | 19000 | 교촌치킨 | 2024-01-15 19:30 | 2024-01-15 20:30 |
문제점:
- 기본키:
주문ID 고객이름은고객번호에만 종속 (부분 함수 종속)메뉴명,가격,브랜드는메뉴번호에만 종속 (부분 함수 종속)- 고객 정보나 메뉴 정보를 수정하려면 여러 행을 수정해야 함 (갱신 이상)
2NF 적용 후:
주문 테이블 (주문ID가 기본키):
| 주문ID | 고객번호 | 메뉴번호 | 주문일시 | 배달예정시간 |
|---|---|---|---|---|
| 1 | C001 | M001 | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 2 | C001 | M002 | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 3 | C002 | M003 | 2024-01-15 19:30 | 2024-01-15 20:30 |
고객 테이블 (고객번호가 기본키):
| 고객번호 | 고객이름 | 전화번호 | 배달주소 |
|---|---|---|---|
| C001 | 김철수 | 010-1234-5678 | 서울시 강남구 테헤란로 123 |
| C002 | 이영희 | 010-9876-5432 | 서울시 서초구 서초대로 456 |
메뉴 테이블 (메뉴번호가 기본키):
| 메뉴번호 | 메뉴명 | 가격 | 브랜드 | 칼로리 |
|---|---|---|---|---|
| M001 | 후라이드치킨 | 18000 | BHC | 1200 |
| M002 | 양념치킨 | 20000 | BHC | 1500 |
| M003 | 간장치킨 | 19000 | 교촌치킨 | 1300 |
개선점:
- 각 테이블이 단일 주제에 집중
- 고객 정보나 메뉴 정보를 한 곳에서만 수정하면 됨
- 데이터 중복 제거
3NF (제3정규형, Third Normal Form)
정의: 2NF를 만족하면서, 이행적 함수 종속(Transitive Functional Dependency)을 제거하는 것. 즉, 기본키가 아닌 속성 간의 종속 관계를 제거해야 한다.
치킨 주문 예시 - 2NF 상태 (여전히 문제 있음):
메뉴 테이블:
| 메뉴번호 | 메뉴명 | 가격 | 브랜드 | 브랜드주소 | 브랜드전화 |
|---|---|---|---|---|---|
| M001 | 후라이드치킨 | 18000 | BHC | 서울시 강남구 | 02-1234-5678 |
| M002 | 양념치킨 | 20000 | BHC | 서울시 강남구 | 02-1234-5678 |
| M003 | 간장치킨 | 19000 | 교촌치킨 | 서울시 서초구 | 02-2345-6789 |
| M004 | 마늘치킨 | 21000 | 교촌치킨 | 서울시 서초구 | 02-2345-6789 |
문제점:
브랜드주소,브랜드전화는브랜드에 종속 (이행적 함수 종속)- 같은 브랜드의 정보가 여러 행에 중복 저장됨
- 브랜드 정보를 수정하려면 여러 행을 수정해야 함 (갱신 이상)
3NF 적용 후:
메뉴 테이블:
| 메뉴번호 | 메뉴명 | 가격 | 브랜드코드 |
|---|---|---|---|
| M001 | 후라이드치킨 | 18000 | B001 |
| M002 | 양념치킨 | 20000 | B001 |
| M003 | 간장치킨 | 19000 | B002 |
| M004 | 마늘치킨 | 21000 | B002 |
브랜드 테이블 (브랜드코드가 기본키):
| 브랜드코드 | 브랜드명 | 브랜드주소 | 브랜드전화 |
|---|---|---|---|
| B001 | BHC | 서울시 강남구 | 02-1234-5678 |
| B002 | 교촌치킨 | 서울시 서초구 | 02-2345-6789 |
개선점:
- 브랜드 정보가 한 곳에만 저장됨
- 브랜드 정보 수정 시 한 행만 수정하면 됨
- 데이터 중복 완전 제거
BCNF (Boyce-Codd Normal Form)
정의: 3NF를 만족하면서, 모든 결정자(Determinant)가 후보키(Candidate Key)가 되도록 하는 것. 즉, 후보키가 아닌 속성이 다른 속성을 결정하는 것을 방지한다.
치킨 주문 예시 - 3NF 상태 (특수한 경우 문제 발생 가능):
주문 테이블:
| 주문ID | 고객번호 | 메뉴번호 | 주문일시 | 배달예정시간 |
|---|---|---|---|---|
| 1 | C001 | M001 | 2024-01-15 18:00 | 2024-01-15 19:00 |
| 2 | C001 | M002 | 2024-01-15 18:00 | 2024-01-15 19:00 |
메뉴 테이블:
| 메뉴번호 | 메뉴명 | 가격 | 브랜드코드 | 배달원이름 | 배달원전화 |
|---|---|---|---|---|---|
| M001 | 후라이드치킨 | 18000 | B001 | 홍길동 | 010-1111-2222 |
| M002 | 양념치킨 | 20000 | B001 | 홍길동 | 010-1111-2222 |
문제점 (가정):
- 만약
배달원전화가배달원이름에만 종속되고,메뉴번호와는 독립적이라면? - 같은 배달원이 여러 메뉴를 배달할 경우
배달원전화가 중복됨 - 하지만
배달원이름이 후보키가 아니므로 3NF는 만족하지만 BCNF는 위반
BCNF 적용 후:
메뉴 테이블:
| 메뉴번호 | 메뉴명 | 가격 | 브랜드코드 | 배달원코드 |
|---|---|---|---|---|
| M001 | 후라이드치킨 | 18000 | B001 | D001 |
| M002 | 양념치킨 | 20000 | B001 | D001 |
배달원 테이블 (배달원코드가 기본키):
| 배달원코드 | 배달원이름 | 배달원전화 |
|---|---|---|
| D001 | 홍길동 | 010-1111-2222 |
| D002 | 김철수 | 010-3333-4444 |
개선점:
- 모든 결정자가 후보키가 됨
- 더 엄격한 정규화로 데이터 무결성 강화
3. 정규화의 장단점
장점
- 데이터 중복 제거: 저장 공간 절약
- 데이터 무결성 보장: 일관성 유지
- 갱신 이상 방지: 한 곳에서만 수정
- 삽입/삭제 이상 방지: 독립적인 데이터 관리
- 유지보수 용이: 구조가 명확함
단점
- 테이블 수 증가: 조인 연산이 많아짐
- 성능 저하 가능성: 복잡한 쿼리로 인한 성능 저하
- 복잡도 증가: 설계와 쿼리가 복잡해짐
4. 비정규화 (Denormalization)
비정규화란?
정규화된 데이터베이스를 성능 향상을 위해 일부러 중복을 허용하는 것을 말한다.
비정규화를 고려하는 경우
- 조회 성능이 중요한 경우: 자주 조회되는 데이터를 중복 저장
- 읽기 중심의 애플리케이션: 읽기 작업이 쓰기 작업보다 훨씬 많은 경우
- 복잡한 조인 회피: 자주 함께 조회되는 데이터를 한 테이블에 저장
치킨 주문 예시 - 비정규화 적용
정규화된 상태 (3NF):
-- 주문 정보 조회 시 조인 필요
SELECT
o.주문ID,
c.고객이름,
m.메뉴명,
m.가격,
o.주문일시
FROM 주문 o
JOIN 고객 c ON o.고객번호 = c.고객번호
JOIN 메뉴 m ON o.메뉴번호 = m.메뉴번호;
비정규화 적용 (성능 향상):
| 주문ID | 고객번호 | 고객이름 | 메뉴번호 | 메뉴명 | 가격 | 주문일시 | 배달예정시간 |
|---|---|---|---|---|---|---|---|
| 1 | C001 | 김철수 | M001 | 후라이드치킨 | 18000 | 2024-01-15 18:00 | 2024-01-15 19:00 |
장점:
- 조인 없이 빠른 조회 가능
- 자주 조회되는 정보를 한 번에 가져옴
단점:
- 메뉴 정보 수정 시 여러 행을 수정해야 함
- 데이터 일관성 유지가 어려움
요약
- 정규화는 데이터 중복을 제거하고 데이터 무결성을 보장하기 위해 테이블을 분해하는 과정입니다.
- 1NF: 원자값만 저장 (하나의 셀에 하나의 값)
- 2NF: 부분 함수 종속 제거 (기본키에 완전 종속)
- 3NF: 이행적 함수 종속 제거 (기본키가 아닌 속성 간 종속 제거)
- BCNF: 모든 결정자가 후보키가 되도록 함
- 정규화는 데이터 일관성을 보장하지만, 과도한 정규화는 성능 저하를 일으킬 수 있습니다.
- 실무에서는 3NF까지 정규화를 기본으로 하고, 성능 문제가 발생할 때만 비정규화를 고려합니다.
'SQL' 카테고리의 다른 글
| SQL_20) 트랜잭션, 님아 그 COMMIT을 누르지마오 (1) | 2025.12.19 |
|---|---|
| SQL_19) DML, DDL, DCL (1) | 2025.12.19 |
| SQL_17) RDBMS란 무엇인가? (0) | 2025.12.15 |
| ORACLE SQL) JOIN 연습문제 (3) | 2025.08.08 |
| DQL 연습문제 (3) | 2025.08.06 |