● 정규화란
데이터 중복을 최소화, 데이터 안정성 확보, 데이터 일관성 유지를 위해
자료의 손실이나 불필요한 정보의 도입없이, 하나의 테이블을 둘 이상으로 분리하는 작업
● 목적
자료 저장에 필요한 저장공간 최소화
자료의 삽입, 갱신, 삭제에 따른 이상현상 제거
자료구조의 안정성 최대화
● 슈퍼키
그 자체로만으로 고유식별자가 되는 것
슈퍼키에 뭘 갖다 붙여도 슈퍼키
● 후보키
슈퍼키의 부분집합으로, 구성 애트리뷰트중 하나라도 제거하면 슈퍼키가 아닌 것
모든 다른 애트리뷰트를 함수적으로 결정하는 애트리뷰트
즉 다른 모든 것을 결정하는 결정자
y가 x에 종속 될 때, x->y 라고 표현
x는 결정자, y는 종속
● 기본키(PK)
여러 후보키 중 대표적인 키 하나가 테이블의 기본키가 된다.
● 제 1정규화(1NF)
테이블은 반드시 하나 이상의 키를 가지고 있어야 하며, 애트리뷰트의 도메인이 오직 원자값만을 포함한다.
반복되는 그룹속성이 존재할 경우, 그 그룹을 분리하여 새로운 엔티티타입을 추가한 후 실체와 1:N관계를 형성해준다.
예제
컴퓨터 학원에서 수강생에 대한 자격증 보유 사항 테이블을 만든다고 가정해보자
[자격증 보유 사항 테이블] 기본키 : 학생번호
학생번호 | 이름 | 주소 | 핸드폰번호 | 자격증 | 자격증번호 | 취득일 |
제1 정규화를 하지 않고 테이블 사용시 쓸데없는 데이터베이스 공간의 낭비가 발생한다.
또한 주소나 핸드폰번호의 변경이 있을 경우 4개의 레코드를 모두 변경해야 한다.
만약 학생번호 1인 김개똥이라는 친구가 자격증을 4개를 가지고 있다면
김개똥에 대한 정보, 즉 회원번호, 이름, 주소, 핸드폰번호등의 정보가 중복해서 저장되어진다.
학생번호 | 이름 | 주소 | 핸드폰번호 | 자격증 | 자격증번호 | 취득일 |
1 | 김개똥 | 하와이 | 019-999-999 | 정보처리 | 12345 | 백수 |
1 | 김개똥 | 하와이 | 019-999-999 | 워드1급 | 23456 | 고2 |
1 | 김개똥 | 하와이 | 019-999-999 | 오라클 | 34512 | 고2 |
1 | 김개똥 | 하와이 | 019-999-999 | MCSE | 12341 | 고3 |
※ 해결 방법 -> 1NF : 반복되는 그룹 속성 분리
중복되는 속성을 4 -> 1으로 줄임
※ 자격증 보유테이블에서 학생번호는 FK이면서 동시에 PK<식별자 관계>
● 제 2정규화(2NF)
기본키 2개 이상으로 구성되는 테이블에서 일부 속성에 대해서만 부분적으로 함수 종속적인 것을 분리
부분함수 종속성을 제거 다시 말해 기본키가 하나 인 경우 제 2정규화를 하지 않고 Pass!!
즉, 후보키가 아닌 애트리뷰트들이 후보키(결정자)에 대해 완전종속
예제
컴퓨터 학원에서 수강생에 대한 교육과정별 평가에 대한 테이블 만들었다고 가정해보자
[학생 성적테이블] 기본키 : 학번, 과정코드
학번 | 과정코드 | 평가 | 과정명 | 기간 |
제2 정규화를 하지 않고 테이블 사용시 과정명 하나만 수정해도 모두 바꾸어야 주어야 한다.
즉, 중복된다. (1NF와 동일) -> 무결성 유지 힘듬
column명 만을 보면 어찌해야 되는지 알 수 없다. 가볍게 data를 삽입해보자
학번 | 과정코드 | 평가 | 과정명 | 기간 |
200 | A01 | A | JAVA | 1개월 |
200 | A02 | A | DB | 2개월 |
201 | B01 | B | ASP | 2개월 |
202 | A01 | A | JAVA | 1개월 |
203 | B01 | C | ASP | 2개월 |
- 모든 data는 [학번,과정코드]의 키로 unique 해진다(중복된 data X). 즉 1NF Pass
- 복합키[학번,과정코드]에 ‘평가’는 완전 종속이 된다.
- 복합키 중 하나인 '과정코드'에 ‘과정명’과 ‘기간’이 부분 종속 되어진다.
그림으로 보자면 ↓
※ 해결 방법 -> 2NF : 부분적 종속 제거
부분적 종속을 제거해준다. 즉 과정코드를 기본키로해서 테이블을 분리 해준다.
● 제 3정규화(3NF)
Primary key가 아닌 일반 column으로 종속되어지는 column 분리.
A -> B, B -> C 그러므로 논리적으로 A -> C. 즉, 이행적 종속 관계를 분리한다.
즉, 후보키가 아닌 애트리뷰트들에서 이행종속이 발생하지 않는다.
예제
제 1정규화 할때 쓴 테이블 가져와 보자. 제 1정규화를 하고 기본키가 하나 이기때문에 제 2정규화 과정은 pass
[교육과정테이블] 기본키 : 학번(FK)
학번 | 자격증 | 자격증번호 |
1 | 정보처리 | 12345 |
1 | 워드1 | 23456 |
2 | 정보처리 | 12345 |
3 | 컴활1 | 87452 |
4 | SCJP | 44444 |
제3 정규화를 하지 않고 테이블 사용시
● 새로운 자격증이 추가 되어 삽입하려고 할때 이 자격증을 취득하고 있는 사람이 존재 하지 않더라도
가상으로 취득 한 것처럼 해야만 삽입이 가능하다
● 학번이 2인 사람이 학원을 그만 두게 되어 내용을 삭제하려고 할때 유지되어야 할 데이터까지 삭제됨(정보처리 12345)
● 특정 학생이 자격증을 취득하게 되면 그 자격증에 의하여 자격증 번호가 결정됨 (이를 이행적 함수 종속성)
즉 기본키가 아닌 속성인 자격증에 의해서 자격증번호가 결정되게 되며 학번으로 자격증번호를 검색 할 수 있다.
학번 -> 자격증, 자격증 -> 자격증번호
∴ 학번 -> 자격증번호
그림으로 보자면 ↓
※ 해결 방법 -> 3NF : 이행적 종속 제거
● 보이스코드 정규화 (BCNF)
BCNF는 제3정규형을 만족하지만, 그 반대는 아니다.
x->y 인 모든 x,y 에 대해 모든 결정자는 후보키여야 한다.
ㅡ> Cycle이 발생하면 BCNF 가 아니다. (이행이랑은 다름)
후보키가 아닌 애트리뷰트가 결정자가 되는 경우 BCNF가 아니다.
요약
정규화
무조건 테이블을 나누는 작업이 아니고 각 단계에서 얻고자 하는 바를 알면 쉽게 해결될 수 있다.
제1 정규화 -> 중복되는 data 분리
- 저장공간을 최소화하기 위해서
- N:N 관계를 1:N으로 바꾸기 위해서
- 수정시 모든 레코드의 data 변경
제 2 정규화(복합키 인 경우만 보면 된다.) -> 부분 종속 분리
- 원하는 바는 제 1정규화와 동일
제 3 정규화 -> 이행적 종속 관계 분리
- 삽입이상 제거
- 삭제이상 제거
● 출처
http://blog.naver.com/PostView.nhn?blogId=force44&logNo=130100972038