SQLD, 정보처리기사 자격증시험에 나오는 주제이므로 숙지 하셔야 할 중요한 내용입니다.
데이터베이스를 설계하고 관리할 때 **정규화(Normalization)**는 매우 중요한 개념입니다. 정규화는 데이터 중복을 줄이고 무결성을 향상시키며, 데이터 삽입, 삭제, 갱신 시 발생할 수 있는 이상(Anomaly) 현상을 방지하는 데 목적이 있습니다. 이 블로그 포스트에서는 1차 정규형부터 5차 정규형까지 각 단계별 개념과 예시를 통해 정규화의 모든 것을 알아보겠습니다.
1. 1차 정규형 (First Normal Form, 1NF)
1차 정규형은 정규화의 가장 기본적인 단계로, 다음 두 가지 조건을 만족해야 합니다.
- 모든 도메인(컬럼)이 원자값(Atomic Value)을 가져야 합니다. 즉, 하나의 컬럼에는 더 이상 분해할 수 없는 하나의 값만 존재해야 합니다.
- 모든 레코드(행)가 고유해야 합니다. 기본 키(Primary Key)를 통해 각 레코드를 유일하게 식별할 수 있어야 합니다.
예시:
아래는 정규화되지 않은 주문 테이블입니다. '상품명' 컬럼에 여러 상품이 쉼표로 구분되어 저장되어 있고, '전화번호' 컬럼에도 여러 전화번호가 포함되어 있습니다.
주문번호 | 고객명 | 전화번호 | 상품명 | 수량 |
101 | 김철수 | 010-1234-5678, 02-123-4567 | 노트북, 마우스 | 1, 1 |
102 | 이영희 | 010-9876-5432 | 키보드 | 2 |
1차 정규형 적용 후: '상품명'과 '전화번호'를 원자값으로 분리하고, 각 레코드가 고유하도록 새로운 테이블로 구성합니다.
주문_상품 테이블:
주문번호 | 상품명 | 수량 |
101 | 노트북 | 1 |
101 | 마우스 | 1 |
102 | 키보드 | 2 |
고객_전화번호 테이블:
고객명 | 전화번호 |
김철수 | 010-1234-5678 |
김철수 | 02-123-4567 |
이영희 | 010-9876-5432 |
2. 2차 정규형 (Second Normal Form, 2NF)
2차 정규형은 1차 정규형을 만족하면서 다음 조건을 추가로 만족해야 합니다.
- 부분 함수 종속성(Partial Functional Dependency)이 없어야 합니다. 즉, 기본 키가 복합 키(Composite Key)로 이루어져 있을 때, 기본 키의 일부분에만 종속되는 속성이 없어야 합니다. 모든 비키(Non-key) 속성은 기본 키 전체에 종속되어야 합니다.
예시:
주문_상품 테이블에서 '주문번호'와 '상품명'이 복합 기본 키라고 가정합니다. 이때 '상품가격'은 '상품명'에만 종속됩니다.
주문번호 | 상품명 | 수량 | 상품가격 |
101 | 노트북 | 1 | 1,000,000 |
101 | 마우스 | 1 | 50,000 |
102 | 키보드 | 2 | 80,000 |
2차 정규형 적용 후:
'상품가격'은 '상품명'에만 종속되므로, 이를 분리하여 새로운 테이블을 생성합니다.
주문_상품 테이블 (기본 키: 주문번호, 상품명):
주문번호 | 상품명 | 수량 |
101 | 노트북 | 1 |
101 | 마우스 | 1 |
102 | 키보드 | 2 |
상품 테이블 (기본 키: 상품명):
상품명 | 상품가격 |
노트북 | 1,000,000 |
마우스 | 50,000 |
키보드 | 80,000 |
3. 3차 정규형 (Third Normal Form, 3NF)
3차 정규형은 2차 정규형을 만족하면서 다음 조건을 추가로 만족해야 합니다.
- 이행적 함수 종속성(Transitive Functional Dependency)이 없어야 합니다. 즉, 기본 키가 아닌 속성이 다른 비키 속성에 종속되는 경우가 없어야 합니다.
예시:
주문 테이블에서 '주문번호'가 기본 키이고, '고객ID'가 '주문번호'에 종속되며, '고객이름'과 '고객주소'는 '고객ID'에 종속됩니다. 이는 '주문번호' '고객ID' '고객이름', '고객주소'와 같은 이행적 함수 종속성이 존재함을 의미합니다.
주문번호 | 고객ID | 고객이름 | 고객주소 |
101 | C001 | 김철수 | 서울시 |
102 | C002 | 이영희 | 부산시 |
3차 정규형 적용 후:
'고객이름'과 '고객주소'가 '고객ID'에 종속되므로, 이를 분리하여 새로운 테이블을 생성합니다.
주문 테이블 (기본 키: 주문번호):
주문번호 | 고객ID |
101 | C001 |
102 | C002 |
고객 테이블 (기본 키: 고객ID):
고객ID | 고객이름 | 고객주소 |
C001 | 김철수 | 서울시 |
C002 | 이영희 | 부산시 |
4. 보이스-코드 정규형 (Boyce-Codd Normal Form, BCNF)
BCNF는 3차 정규형보다 더 엄격한 정규형으로, 다음과 같은 조건을 만족해야 합니다.
- 모든 결정자(Determinant)는 후보 키(Candidate Key)여야 합니다. 즉, 어떤 속성이 다른 속성을 결정한다면(함수 종속성을 가진다면), 그 속성은 반드시 후보 키여야 합니다. BCNF는 다중 후보 키가 존재하고, 그 후보 키들이 서로 겹치는 부분이 있을 때 발생할 수 있는 이상 현상을 해결하는 데 유용합니다.
예시:
수강 테이블에 '학생ID', '과목명', '교수명'이 있습니다. '학생ID'와 '과목명'은 복합 후보 키이고, '교수명'은 '과목명'에 종속되며, 한 과목을 여러 교수가 가르칠 수 있고 한 교수가 여러 과목을 가르칠 수 있습니다. 하지만 어떤 특정 과목은 특정 교수만 가르칠 수 있다고 가정해 봅시다.
학생ID | 과목명 | 교수명 |
1 | 데이터베이스 | 김교수 |
2 | 데이터베이스 | 김교수 |
1 | 알고리즘 | 이교수 |
여기서 '과목명' '교수명' 이라는 함수 종속성이 존재합니다 (특정 과목은 특정 교수만 가르침). 하지만 '과목명'은 후보 키가 아닙니다. 이 경우 BCNF를 위반합니다.
BCNF 적용 후:
수강 테이블을 '학생ID'와 '과목명'의 관계를 나타내는 테이블과 '과목명'과 '교수명'의 관계를 나타내는 테이블로 분리합니다.
수강 테이블 (기본 키: 학생ID, 과목명):
학생ID | 과목명 |
1 | 데이터베이스 |
2 | 데이터베이스 |
1 | 알고리즘 |
과목_교수 테이블 (기본 키: 과목명):
과목명 | 교수명 |
데이터베이스 | 김교수 |
알고리즘 | 이교수 |
5. 4차 정규형 (Fourth Normal Form, 4NF)
4차 정규형은 BCNF를 만족하면서 다음 조건을 추가로 만족해야 합니다.
- 다치 종속성(Multi-valued Dependency, MVD)이 없어야 합니다. MVD는 한 릴레이션에 두 개 이상의 독립적인 다치 종속성이 존재할 때 발생합니다. 즉, A B (A는 B를 다치 종속시킨다)이고 A C (A는 C를 다치 종속시킨다)일 때, B와 C가 서로 독립적이라면 4NF를 위반할 수 있습니다.
예시:
학생_취미_과외 테이블에서 한 학생은 여러 취미를 가질 수 있고, 여러 과외를 받을 수 있다고 가정합니다. 이때 '취미'와 '과외'는 서로 독립적인 관계입니다.
학생ID | 취미 | 과외 |
1 | 축구 | 수학 |
1 | 음악 | 수학 |
1 | 축구 | 영어 |
여기서 '학생ID' '취미' (학생ID는 여러 취미를 가질 수 있음) 이고 '학생ID' '과외' (학생ID는 여러 과외를 받을 수 있음) 입니다. '취미'와 '과외'는 서로 독립적입니다.
4차 정규형 적용 후:
다치 종속성을 분리하여 독립적인 테이블로 나눕니다.
학생_취미 테이블 (기본 키: 학생ID, 취미):
학생ID | 취미 |
1 | 축구 |
1 | 음악 |
학생_과외 테이블 (기본 키: 학생ID, 과외):
학생ID | 과외 |
1 | 수학 |
1 | 영어 |
5차 정규형 (Fifth Normal Form, 5NF)
5차 정규형은 4차 정규형을 만족하면서 다음 조건을 추가로 만족해야 합니다.
- 조인 종속성(Join Dependency)이 없어야 합니다. 5차 정규형은 테이블을 더 이상 분해할 수 없는 조인 종속성이 존재하지 않도록 합니다. 즉, 하나의 테이블을 여러 개의 작은 테이블로 분해했을 때, 이들을 다시 조인해도 원래 테이블과 동일한 데이터를 복원할 수 있어야 합니다. 만약 분해된 테이블들을 조인했을 때 원래 테이블에 없던 튜플이 생성된다면(Join Anomaly), 5NF를 위반한 것입니다. 현실적으로 5차 정규형까지 적용하는 경우는 드뭅니다.
예시:
공급업체_부품_프로젝트 테이블에서 특정 공급업체는 특정 부품을 특정 프로젝트에만 공급한다고 가정합니다.
공급업체 | 부품 | 프로젝트 |
A | CPU | X |
A | RAM | Y |
B | CPU | Y |
이 테이블은 특정 조인 종속성을 가지고 있을 수 있습니다. 만약 이 테이블을 공급업체_부품, 부품_프로젝트, 공급업체_프로젝트로 분해한 후 다시 조인했을 때 원본 테이블에 없던 조합이 생긴다면 5NF를 위반한 것입니다. 5NF는 이러한 다대다(Many-to-Many) 관계가 세 개 이상의 엔티티에 걸쳐 복잡하게 얽혀 있을 때 고려됩니다.
5차 정규형 적용 후:
조인 종속성을 제거하기 위해 더 이상 분해할 수 없는 테이블로 나눕니다.
공급업체_부품 테이블:
공급업체 | 부품 |
A | CPU |
A | RAM |
B | CPU |
부품_프로젝트 테이블:
부품 | 프로젝트 |
CPU | X |
RAM | Y |
CPU | Y |
공급업체_프로젝트 테이블:
공급업체 | 프로젝트 |
A | X |
A | Y |
B | Y |
이렇게 3개의 테이블로 분해하여 각 관계의 최소 집합을 나타냄으로써 조인 종속성을 제거하고 데이터 무결성을 극대화합니다.
정규화는 언제까지 해야 할까요?
정규화는 데이터베이스의 효율성을 높이고 이상 현상을 방지하는 데 필수적이지만, 과도한 정규화는 조인(Join) 연산의 증가로 인해 쿼리 성능 저하를 야기할 수 있습니다. 일반적으로 3차 정규형 또는 BCNF까지 정규화를 수행하는 것이 일반적입니다. 시스템의 요구 사항과 성능을 고려하여 적절한 정규화 수준을 결정하는 것이 중요합니다.
데이터베이스 정규화에 대한 이해가 여러분의 데이터베이스 설계에 큰 도움이 되기를 바랍니다! 궁금한 점이 있다면 언제든지 댓글로 남겨주세요.
'DB|SQL' 카테고리의 다른 글
알맞는 데이터 베이스 고르기와 CAP theorem (0) | 2024.03.31 |
---|---|
데이터 베이스 MVCC(Multiversion Concurrency Control) (4) | 2024.02.05 |
PSQL 반복적인 Update query 실행시 발생 하는 상황 - SQLSTATE(08006) (2) | 2024.01.06 |