GiYeong

정규화 본문

CS/DB

정규화

gy2710 2022. 6. 21. 01:40

정규화(Normalization)의 목표는 테이블 간의 중복된 데이터를 허용하지 않는 것이다.

이를 통해 데이터의 무결성(Integrity)를 유지할 수 있으며, DB의 저장 용량을 줄일 수 있다.

테이블을 어떻게 분해하는지에 따라 정규화의 단계가 달라진다.

데이터의 무결성
데이터의 정확성, 일관성, 유효성이 유지되는 것
정확성이란 중복이나 누락이 없는 상태를 뜻하고, 일관성은 원인과 결과의 의미가 연속적으로 보장되어 변하지 않는 상태

 

제1 정규화

 

테이블의 컬럼이 원자값(Atomic Value, 하나의 값)을 가지도록 테이블을 분해하는 것이다.

학생 이름 나이 수강 과목
A 13 수학, 국어
B 14 수학
C 12 과학

위 테이블에서 경기도는 여러 개의 시를 가지고 있기 때문에 제1 정규형을 만족하지 못한다.

이를 제1 정규화하여 분해하면 아래와 같은 테이블이 된다.

학생 이름 나이 수강 과목
A 13 수학
A 13 국어
B 14 수학
C 12 과학

 

제2 정규화

 

제2 정규화는 제1 정규화가 진행된 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해하는 것이다.

완전 함수 종속
기본키 중, 특정 컴럼에만 종속된 컬럼(부분적 종속)이 없어야 한다.

위 테이블의 경우 기본키는 (학생 이름, 수강 과목) 두 개로 볼 수 있다. 이 두개가 합쳐져야 하나의 row를 구분할 수 있다.

하지만 나이의 경우, 기본키 중 학생 이름에만 종속되어 있다. 즉, 학생 이름 컬럼의 값을 알면 나이의 값을 알 수 있다.

따라서 나이가 두 번 들어가는 것은 불필요하다.

위 테이블을 제2 정규화를 통해 분해하면 아래와 같은 테이블이 된다.

학생 이름 나이
A 13
B 14
C 12
학생 이름 수강 과목
A 수학
A 국어
B 수학
C 과학

 

제3 정규화

학생 ID 학생 이름 생년월일 우편번호

위와 같은 테이블이 있다면, 학생 ID가 기본키이고, 기본키가 하나이므로 2차 정규형은 만족한다.

하지만, 우편번호를 알면 구, 군, 시를 결정할 수 있다.

또한 여러 명의 학생들이 같은 우편번호를 갖는 경우, 우편번호만 알면 구, 군, 시가 결정되기 때문에 해당 컬럼들에는 중복된 데이터가 생길 가능성이 있다.

3차 정규화는 기본키를 제외한 속성들 간의 이행적 함수 종속이 없도록 하는 것이다.

이행적 함수 종속이 없도록 한다는 의미
기본키 이외의 다른 컬럼이 그 외의 다른 컬럼을 결정할 수 없도록 한다.

위 테이블을 3차 정규화를 통해 분해하면 아래와 같이 된다.

학생 ID 학생 이름 생년월일 우편번호
우편 번호

이를 통해 논리적인 단위(학생, 주소)로 분리되고, 데이터의 중복성(redundancy)도 줄었음을 알 수 있다.

 

BCNF(Boyce and Codd Normal Form)

3차 정규화를 더 강화한 정규화로서, 3차 정규형을 만족하면서 모든 결정자가 후보키 집합에 속하도록 하는 것이다.

학생 번호 과목 교수 학점
1 C/C++ 교수A A+
2 Java 교수B A
3 Java 교수B A

위 테이블의 경우 후보키(수퍼키 중, 최소성을 만족하는 키)는 (학생 번호, 과목)이다.

(학생 번호, 과목)은 하나의 row를 유일하게 구분할 수 있다. 하지만 이 테이블에서 결정자는 교수이다.(교수가 한 과목만 강의할 수 있다고 가정)

즉, 교수가 정해지면 과목이 결정된다.

하지만 교수는 이 테이블의 후보키가 아니다. 따라서 위 테이블은 BCNF를 만족하지 않는다.

 

정리하자면, 3차 정규형을 만족하면서 BCNF는 만족하지 않는 경우는 일반 컬럼이 후보키를 결정하는 경우이다.

 

또한 위 테이블은 데이터가 중복되고, 교수가 강의하는 과목이 바뀌면 2개의 row를 갱신해야 하는 갱신 이상이 발생한다.

 

위 테이블을 BCNF를 통해 분해하면 아래와 같이 된다.

교수 과목
교수A C/C++
교수B Java
학생 번호 과목 학점
1 C/C++ A+
2 Java A
3 Java A

'CS > DB' 카테고리의 다른 글

Redis, Memcached  (0) 2022.08.31
RDBMS / NoSQL  (0) 2022.06.21
JOIN  (0) 2022.06.21
트랜잭션  (0) 2022.06.18
DB에서 인덱스를 사용하는 이유  (0) 2022.06.18
Comments