정규화는 비정규 릴레이션을 시작으로 총 제5 정규형가지 6단계를 거친다.
1NF → 2NF → 3NF → BCNF → 4NF → 5NF
도부이결다조
정규형의 종류
여기서 1NF부터 BCNF까지 알아보자.
모든 필드가 원자값을 가져야 함.
즉, 어떤 릴레이션이 항상 원자 값만 포함하게 되어 있으면 제1 정규형을 만족한다.
Before
After
하지만, 고객의 등급과 할인율을 추가하고 싶지만 기본키인 이벤트 번호가 없다면 삽입할 수 없는 삽입 이상, 고객과 이벤트에 대한 당첨여부만 지우고 싶지만 고객의 등급 및 할인율까지 필요한 정보마저 지워버리는 삭제 이상이 발생한다.
1NF를 만족하며, 기본 키에 대해 부분 종속이 없어야 함.
위 사진을 예로 들면, 고객아이디
와 이벤트번호
가 기본키로 되어 있지만, 등급과 할인율은 이벤트 번호가 없어도 논리적으로 종속 관계를 갖는다.
즉, 이렇게 기본키의 부분적으로만 종속된 요소를 분리하여 완전 함수 종속이 될 수 있게 하는 것을 제2 정규형이라고 한다.
하지만, 고객 릴레이션에서 등급에 따른 할인율을 변경한다면 다른 튜플의 같은 등급과 다른 할인율을 나타낼 수 있는 갱신 이상, 고객의 등급만 삭제하고 싶지만 함수적 종속관계인 할인율까지 삭제되는 삭제 이상, 새로운 등급이 생겨 해당 등급의 할인율만 삽입하고 싶지만 고객의 아이디가 없으면 삽입할 수 없는 삽입 이상이 발생함.
→ 이는 고객 릴레이션의 이행적 함수 종속 관계 때문.
2NF를 만족하며, 기본 키에 대해 이행적 종속이 없어야 함.
즉, 이행적 함수 종속을 분해함.
등급이 고객아이디에 종속됨. 할인율이 등급에 종속됨. 즉, 고객아이디->등급->할인율인 이행적 함수 종속을 분해함.
3NF를 만족하며, 모든 결정자가 후보키 집합에 속해 있어야 한다.
이를 위한 하는 구조를 보면서 알아보자.
위반하는 경우
1. 1NF를 만족한다고 가정한다.
2. 기본키({A,B})가 아닌 모든 속성(C, D, E)이 기본키에 완전 함수 종속이므로 2NF를 만족한다.
3. 기본키({A,B})가 아닌 모든 속성(C, D, E)이 기본키에 이행적 함수 종속이 되지 않으므로 3NF를 만족한다.하지만, C속성이 기본키 집합 중 B를 결정하고 있다.
이처럼, 결정자(C)가 후보키 집합({A,B})에 속해있지 않은 상태가 BCNF를 위반한 상태다.
이처럼, {STUDENT, COURSE}를 기본키로 한 릴레이션은 INSTRUCTOR 속성을 결정하고 있다. 하지만 INSTRUCTOR가 COURSE를 결정하는 구조도 나타내고 있다.
이러한 구조에서 발생할 수 있는 이상 현상에 대해 알아보자.
- 삽입 이상
C Programming이라는 Course가 Kenneth Lane Thompson에 의해 열렸다고 가정하자. 하지만, 기본키인 수강생이 한 명도 없으면 해당 과정은 추가할 수 없다.- 갱신 이상
James Gosling 이 담당하는 강의가 바뀌게 될 경우 수강생의 수만큼 갱신해줘야 하므로 하나라도 빠뜨리면 데이터 불일치 문제가 발생한다.- 삭제 이상
만약 모찌라는 학생이 자퇴하여 해당 튜플을 삭제하게 된다면, 애먼 Computer Architecture와
Alan Turing도 사라지게 된다.
이러한 이상 현상을 해결하기 위해 분해해보자.
이처럼 기본키 집합을 분해하여 후보키가 아닌 결정자를 기본키로 하는 테이블을 만든다면, 두 테이블 모두 BCNF까지 만족하는 테이블 2개를 만들 수 있게 된다.
정규화를 거듭하게 되면 테이블이 분리되고 그만큼 Join 연산이 많이 일어나게된다.
데이터 관리 측면에서는 좋을 순 있지만, 자주 조회하거나 접근하는 테이블에는 성능 저하로 이어질 수 있다.
이러한 문제를 해결하기 위해 일부러 정규화를 되돌리는 것을 반정규화라고 한다.
출처
https://yaboong.github.io/database/2018/03/10/database-normalization-2/
https://velog.io/@khs0415p/7-%EC%A0%95%EA%B7%9C%ED%98%95%EA%B3%BC-%EC%A0%95%EA%B7%9C%ED%99%94