데이터베이스 정규화 (Normalization)
앞선 포스팅에서 데이터베이스의 잘못된 설계로 발생하는 이상(Anomaly)과, 함수적 종속에 대해 알아보았다.
데이터 중복으로 발생하는 이상 현상을 제거하기 위해서는, 데이터베이스의 테이블을 올바르게 재구성해야 할 것이다.
이처럼 데이터베이스 설계 단계에서 중복이 최소화되도록 구조화하는 과정을 정규화(Normalization)라 하며, 이렇게 정규화된 정도를 정규형(NF, Normal Form)이라 한다.
정규형에는 1NF, 2NF, 3NF, BCNF, 4NF, 5NF, 6NF 가 존재한다. 차수가 높아질수록 정규형의 조건이 까다로워지며, 더 높은 정규화 정도를 가진다.
이번 포스팅에서는 1NF부터 BCNF까지의 정규형을 알아보자.
제 1 정규형 (1NF, First Normal Form) : 도메인의 원자성
다음과 같은 예제 테이블을 보자.
USER_ID | USER_NAME | ORDERED_PRODUCT | ADDRESS | MEMBERSHIP |
11254824 | LEE | MOUSE, KEYBOARD | ULSAN | TRUE |
18574381 | PARK | SPEAKER | SEOUL | TRUE |
89834230 | KIM | MONITOR, MOUSE | DAEGU | FALSE |
위 테이블은 제 1정규형을 만족하지 않는다. ORDERED_PRODUCT 에 주목하자.
관계형 데이터베이스는 행 도메인에서 각각 정확히 한 개의 값만을 허용하기 때문에, ORDERED_PRODUCT 도메인은 원자성을 갖지 못하며, 이는 제 1정규형의 조건을 위반한다.
따라서, 다음과 같이 테이블을 수정해야 한다.
USER_ID | USER_NAME | ORDERED_PRODUCT | ADDRESS | MEMBERSHIP |
11254824 | LEE | MOUSE | ULSAN | TRUE |
11254824 | LEE | KEYBOARD | ULSAN | TRUE |
18574381 | PARK | SPEAKER | SEOUL | TRUE |
89834230 | KIM | MONITOR | DAEGU | FALSE |
89834230 | KIM | MOUSE | DAEGU | FALSE |
제 2 정규형 (2NF, Second Normal Form) : 부분 함수적 종속 제거
위에서 수정한 테이블은 복합 키 {USER_ID, ORDERED_PRODUCT}를 기본 키로 한다.
하지만 USER_ID를 알면 USER_NAME과 ADDRESS, MEMBERSHIP은 자동으로 따라 오는 정보들이다. LEE 회원의 두 주문 건에 대해 USER_NAME, ADDRESS, MEMBERSHIP은 중복된 데이터를 담고 있다.
즉, USER_ID가 USER_NAME, ADDRESS, MEMBERSHIP의 결정자이다.
기본 키는 {USER_ID, ORDERED_PRODUCT} 지만, USER_NAME, ADDRESS, MEMBERSHIP은 USER_ID에만 종속된다.
이를 부분 함수적 종속이라 하며, 제 2 정규형을 만족하기 위해선 이 부분 함수적 종속이 없어야 한다.
따라서, 테이블을 다음과 같이 수정한다.
[USER_INFO]
USER_ID | USER_NAME | ADDRESS | MEMBERSHIP |
11254824 | LEE | ULSAN | TRUE |
18574381 | PARK | SEOUL | TRUE |
89834230 | KIM | DAEGU | FALSE |
[USER_ORDER]
USER_ID | ORDERED_PRODUCT |
11254824 | KEYBOARD |
11254824 | MOUSE |
18574381 | SPEAKER |
89834230 | MONITOR |
89834230 | MOUSE |
제 3 정규형 (3NF, Third Normal Form) : 이행 함수적 종속 제거
다음 상품 정보표를 보자.
PRODUCT_CODE | PRODUCT_NAME | COMPANY | COMPANY_ADDRESS |
12450001 | KEYBOARD | ABC_ELEC | SEOUL |
13528723 | MOUSE | ABC_ELEC | SEOUL |
76242315 | SPEAKER | DEF_ELEC | DAEGU |
85782421 | MONITOR | GHI_ELEC | USA |
위 테이블에 존재하는 다음과 함수적 종속에 주목하자.
- PRODUCT_CODE → COMPANY
- COMPANY → COMPANY_ADDRESS
- PRODUCT_CODE → COMPANY_ADDRESS
상품 코드는 제조사명의 결정자이고, 제조사명은 제조사 주소의 결정자이다. 또한, 상품 코드는 제조사 주소의 결정자이다.
논리적으로 틀린 부분은 없지만, 정말로 상품 코드를 알면 제조사의 주소를 알 수 있다고 말할 수 있을까? 제조사의 주소는 제조사 명에 의해서 결정되는 것이 개념적으로 더 잘 들어맞는다.
위의 세 함수적 종속을 이행 함수적 종속이라 한다. 이행 함수적 종속은 다음과 같이 표현된다.
X → Y 이고 Y → Z 일 때, X → Z
제 3 정규형은 이행 함수적 종속을 제거함으로써 만족할 수 있다. 위 테이블을 제 3 정규형을 만족하도록 수정하면 다음과 같다.
[PRODUCT_COMPANY]
PRODUCT_CODE | PRODUCT_NAME | COMPANY_NAME |
12450001 | KEYBOARD | ABC_ELEC |
13528723 | MOUSE | ABC_ELEC |
76242315 | SPEAKER | DEF_ELEC |
85782421 | MONITOR | GHI_ELEC |
[COMPANY]
COMPANY_NAME | COMPANY_ADDRESS |
ABC_ELEC | SEOUL |
DEF_ELEC | DAEGU |
GHI_ELEC | USA |
보이스-코드 정규형 (BCNF, Boyce-Codd Normal Form) : 후보 키가 아닌 결정자 제거
이번에는 다음과 같은 주문 테이블을 보자.
USER_ID | PRODUCT_CODE | SHIPMENT_ID | SHIPPER_NAME |
11254824 | 12450001 | 46825178 | CHOI |
11254824 | 13528723 | 46825178 | CHOI |
18574381 | 13528723 | 48873275 | BAE |
위 테이블에서 키는 {USER_ID, PRODUCT_CODE}이다.
하지만, SHIPPER_NAME은 SHIPMENT_ID에 의해 결정된다. 이 때, SHIPMENT_ID는 후보 키가 아니므로, BCNF를 만족하지 못한다.
따라서 다음과 같이 테이블을 수정하여 BCNF를 만족하도록 한다.
USER_ID | PRODUCT_CODE | SHIPMENT_ID |
11254824 | 12450001 | 46825178 |
11254824 | 13528723 | 46825178 |
18574381 | 13528723 | 48873275 |
SHIPMENT_ID | SHIPPER_NAME |
46825178 | CHOI |
48873275 | BAE |
'데이터베이스' 카테고리의 다른 글
[데이터베이스] 정규화 : 이상(Anomaly), 함수적 종속성 (Functional Depenency) (0) | 2021.03.25 |
---|---|
[데이터베이스] 트랜잭션 (Transaction) (0) | 2021.03.19 |