먼저, 3NF(제3정규형)에 대해 살펴보겠습니다. 3NF는 2NF를 만족하면서, 모든 비주요 속성(Non-Prime Attribute)이 기본 키(Primary Key)에 대해 이행적 종속(Transitive Dependency)을 가지지 않아야 한다는 규칙을 요구합니다.
이행적 종속이란 A → B, B → C인 관계가 있을 때, A → C도 성립하는 것을 의미합니다. 이러한 종속이 발생하면 테이블 내에 중복 데이터가 생성될 수 있습니다.
다음과 같은 테이블을 예로 들어 보겠습니다:
| 어카운트 ID | 은행 이름 | 계좌 번호 | 등급 | 월급 비율 | 임직원 ID | 임직원 이름 |
|---|---|---|---|---|---|---|
| 1 | 국민은행 | 123-456 | 스타 | 0.7 | 101 | 소니 |
| 2 | 우리은행 | 987-654 | 실버 | 0.3 | 101 | 소니 |
| 3 | 국민은행 | 654-321 | 로얄 | 1.0 | 102 | 메쉬 |
이 테이블에서 임직원 이름은 임직원 ID에 의해 결정됩니다. 또한, 어카운트 ID가 같으면 임직원 ID도 같으므로, 어카운트 ID는 임직원 이름을 이행적으로 결정합니다. 이로 인해 임직원 이름에 중복 데이터가 발생할 수 있습니다.
이 문제를 해결하기 위해, 3NF는 모든 비주요 속성이 어떤 키에 대해서도 이행적으로 종속되면 안 된다는 규칙을 제시합니다.
위 테이블의 중복을 제거하기 위해, 임직원 ID와 임직원 이름을 별도의 테이블로 분리해 봅시다.
임직원 테이블
| 임직원 ID | 임직원 이름 |
|---|---|
| 101 | 소니 |
| 102 | 메쉬 |
어카운트 테이블
| 어카운트 ID | 은행 이름 | 계좌 번호 | 등급 | 월급 비율 | 임직원 ID |
|---|---|---|---|---|---|
| 1 | 국민은행 | 123-456 | 스타 | 0.7 | 101 |
| 2 | 우리은행 | 987-654 | 실버 | 0.3 | 101 |
| 3 | 국민은행 | 654-321 | 로얄 | 1.0 | 102 |
이렇게 테이블을 분리하면 임직원 이름에 대한 중복 데이터가 사라지고, 3NF를 만족하게 됩니다.
예를 들어, 다음과 같은 함수 종속성이 존재한다고 가정해 봅시다:
등급 → 은행 이름이 경우, 등급이 은행 이름을 결정하지만, 등급은 슈퍼키가 아니므로 BCNF를 위반하게 됩니다.
이 문제를 해결하기 위해 등급과 은행 이름을 별도의 테이블로 분리합니다.
등급 테이블
| 등급 | 은행 이름 |
|---|---|
| 스타 | 국민은행 |
| 실버 | 우리은행 |
| 로얄 | 국민은행 |
어카운트 테이블
| 어카운트 ID | 계좌 번호 | 월급 비율 | 임직원 ID | 등급 |
|---|---|---|---|---|
| 1 | 123-456 | 0.7 | 101 | 스타 |
| 2 | 987-654 | 0.3 | 101 | 실버 |
| 3 | 654-321 | 1.0 | 102 | 로얄 |
이로써 등급이 슈퍼키가 되어 BCNF를 만족하게 됩니다.
이번 포스트에서는 3NF와 BCNF를 적용하여 데이터베이스를 정규화하는 방법을 살펴보았습니다. 테이블을 분리하고 중복 데이터를 제거함으로써 데이터베이스의 효율성을 높일 수 있음을 확인했습니다.
정규화는 데이터베이스 설계에서 매우 중요한 과정이며, 데이터의 무결성과 일관성을 유지하는 데 큰 도움이 됩니다. 다음 포스트에서는 인덱스를 통해 쿼리 성능을 최적화하는 방법을 다루겠습니다.
https://www.youtube.com/watch?v=aL0XXc1yGPs&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe