정규화란?
정규화(Normalization)는 관계형 데이터베이스에서 데이터를 구조화하여 데이터 중복을 최소화하고 무결성을 보장하기 위한 과정이다.
주요 목적은 다음과 같다.
- 데이터 중복 제거
- 저장 공간 효율적 사용
- 데이터 일관성 유지
- 데이터 갱신 시 이상 현상 방지
하지만 정규화 진행 시 다음과 같은 단점이 발생할 수 있다.
- 복잡한 쿼리 : 여러 테이블로 분할되어 쿼리가 복잡해질 수 있다.
- 성능 저하 : 높은 정규화로 인해 일부 쿼리의 성능이 저하될 수 있다.
(JOIN 연산같은 경우 성능 저하 요인이 됨.)
정규화는 1NF, 2NF, 3NF, BCNF, 4NF, 5NF가 있다. 순서대로 살펴보자.
제 1 정규형 (1NF)
- 모든 열이 원자값(Atomic Value)을 가져야한다.
- 각 컬럼은 유일한 이름을 가져야하며, 컬럼의 순서는 상관 없어야 한다.
- 테이블의 각 셀에 단일 값만 존재해야 하며, 반복되는 그룹이 없어야 한다.
예시)
다음과 같이 비정규화된 테이블이 있다고 하자.
| OrderID | Customer | Items |
|---------|----------|------------------|
| 1 | John | Apple, Banana |
| 2 | Jane | Orange, Grape |
위의 테이블은 Items의 값이 원자값이 아니다. 이 테이블을 1NF로 변환시켜보자.
| OrderID | Customer | Item |
|---------|----------|--------|
| 1 | John | Apple |
| 1 | John | Banana |
| 2 | Jane | Orange |
| 2 | Jane | Grape |
1NF로 변환 된 테이블은 모든 열이 원자값만 가지고 있음을 확인할 수 있다.
제 2 정규형 (2NF)
- 1NF를 만족해야 한다.
- 기본 키의 부분 집합에 종속된 모든 속성을 제거해야한다.
- 즉, 모든 컬럼이 완전 함수적 종속을 만족해야한다.
예시)
아래와 같은 1NF 테이블이 있다고 가정하자
| OrderID | ProductID | ProductName |
|---------|-----------|-------------|
| 1 | 1 | Apple |
| 1 | 2 | Banana |
| 2 | 3 | Orange |
| 2 | 4 | Grape |
이 테이블에서 기본키는 OrderID와 ProductID의 복합키이다. 이 기본키는 ProductName을 결정하고 있다.
(OrderID, ProductID) → (ProductName)
하지만 ProductID 단일 컬럼으로도 ProductName을 결정할 수 있다. 즉, 기본키의 부분집합에 종속된 속성이 있다는 것이다.
(ProductID) → (ProductName)
이를 분해하여 별도의 테이블로 관리하도록 2NF 변환시키면 아래와 같다.
Orders Table
| OrderID | ProductID |
|---------|-----------|
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
Products Table
| ProductID | ProductName |
|-----------|-------------|
| 1 | Apple |
| 2 | Banana |
| 3 | Orange |
| 4 | Grape |
모든 테이블의 기본키가 완전함수종속을 만족하고 있음을 확인할 수 있다.
제 3 정규형 (3NF)
- 2NF를 만족해야 한다.
- 이행적 종속을 제거한다.
ㄴ 이행적 종속이란 A→B, B→C일 때 A→C가 성립되는 것 - 기본키를 제외한 속성들 간의 이행 종속성이 없어야 한다.
예시)
아래와 같은 2NF 테이블이 있다고 가정하자.
| OrderID | ProductID | ProductName | SupplierID | SupplierName |
|---------|-----------|-------------|------------|--------------|
| 1 | 1 | Apple | 1 | Supplier A |
| 1 | 2 | Banana | 2 | Supplier B |
| 2 | 3 | Orange | 1 | Supplier A |
| 2 | 4 | Grape | 2 | Supplier B |
ProductID → SupplierID
SupplierID → SupplierName
ProductID → SupplierName
A→B, B→C일 때 A→C가 성립된다.
즉, 이행적 종속이 있으므로 이를 제거하여 3NF로 변환시켜보자.
Orders Table
| OrderID | ProductID | SupplierID |
|---------|-----------|------------|
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 2 | 3 | 1 |
| 2 | 4 | 2 |
Products Table
| ProductID | ProductName |
|-----------|-------------|
| 1 | Apple |
| 2 | Banana |
| 3 | Orange |
| 4 | Grape |
Suppliers Table
| SupplierID | SupplierName |
|------------|--------------|
| 1 | Supplier A |
| 2 | Supplier B |
각 테이블은 기본키를 제외한 모든 이행적 종속이 존재하지 않음을 확인할 수 있다.
보이스-코드 정규형 (BCNF)
- 3NF의 특수한 형태이다.
- 3NF를 만족하면서, 모든 결정자가 후보키여야 한다.
즉, 함수적 종속성을 가진 모든 속성에 대해 결정자가 후보키가 되어야 한다.
예시)
아래는 3NF는 만족하지만 BCNF는 만족하지 않는 테이블이다.
| StudentID | Course | Instructor |
|-----------|------------|------------|
| 1 | Math | Prof. Kim |
| 2 | Science | Prof. Lee |
| 3 | Math | Prof. Park |
| 4 | Science | Prof. Lee |
| 5 | Math | Prof. Kim |
함수 종속성을 살표보면
StudentID -> Cource, Instructor
Course -> Instructor
즉 Course는 Instructor를 결정하지만, Course가 후보키인 것은 아니다.
때문에 테이블을 분할하여 BCNF 변환을 할 수 있다.
Courses Table
| Course | Instructor |
|---------|------------|
| Math | Prof. Kim |
| Science | Prof. Lee |
Students Table
| StudentID | Course |
|-----------|---------|
| 1 | Math |
| 2 | Science |
| 3 | Math |
| 4 | Science |
| 5 | Math |
각각의 테이블을 보면 모든 결정자가 후보키가 되어 BCNF를 만족함을 볼 수 있다.
제 4 정규형 (4NF)
- BCNF를 만족해야 한다.
- 다치 종속을 제거해야 한다.
ㄴ 다치종속이란 하나의 속성이 다른 속성 집합에 종속되지만, 그 속성 집합이 서로 독립적인 경우를 말한다.
예시)
| StudentID | Course | Hobby |
|-----------|----------|-----------|
| 1 | Math | Soccer |
| 1 | Math | Music |
| 1 | Science | Soccer |
| 1 | Science | Music |
| 2 | Math | Reading |
| 2 | English | Reading |
위의 테이블은 다치 종속이 있는 테이블이다.
StudentID별로 여러 Course와 Hobby를 가질 수 있으나 이 둘은 서로 독립적이다.
다치 종속을 제거하는 4NF변환을 하면 아래와 같다.
Students_Courses Table
| StudentID | Course |
|-----------|----------|
| 1 | Math |
| 1 | Science |
| 2 | Math |
| 2 | English |
Students_Hobbies Table
| StudentID | Hobby |
|-----------|-----------|
| 1 | Soccer |
| 1 | Music |
| 2 | Reading |
두개의 독립적인 테이블로 분리하여 다치종속을 제거하였다.
제 5 정규형 (5NF)
- 4NF를 만족해야 한다.
- 조인 종속을 제거해야 한다.
ㄴ 조인 종속이란 테이블을 분해했을 때 원래의 테이블로 복원할 수 있어야 하는 조건을 의미한다.
즉, 모든 조인 종속이 후보키에 의해 결정되도록 해야한다.
예시)
아래의 테이블은 조인 종속이 있는 테이블 예시이다.
| ProjectID | EmployeeID | Skill |
|-----------|------------|-----------|
| 1 | 1 | Analysis |
| 1 | 2 | Design |
| 2 | 1 | Coding |
| 2 | 3 | Testing |
ProjectID 당 여러 EmployeeID가 있을 수 있고, EmployeeID 당 여러 Skill을 가질 수 있다.
이를 5NF변환하면 아래 테이블과 같다.
Projects_Employees Table
| ProjectID | EmployeeID |
|-----------|------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
Employees_Skills Table
| EmployeeID | Skill |
|------------|-----------|
| 1 | Analysis |
| 1 | Coding |
| 2 | Design |
| 3 | Testing |
두개의 독립적인 테이블로 분리하여 조인 종속을 제거할 수 있다.
'Computer Science > Database' 카테고리의 다른 글
Redis (1) | 2024.11.27 |
---|---|
이상현상(Anomaly) (0) | 2024.11.26 |
SQL과 NoSQL (2) | 2024.11.24 |
SQL injection 종류와 방지 (0) | 2024.11.23 |
조인(JOIN) - ANSI SQL, MySQL, Oracle 예 (0) | 2024.11.22 |