09. 정규화
속성들의 친밀도를 정확히 판단하고, 기준에 따라 릴레이션을 구성하는 방법인 정규화를 학습한다.
9.1. 정규화의 개념과 이상 현상
9.1.1. 정규화의 개념
정규화(normalizations)란 데이터 베이스의 설계 및 검증 방법으로 이상 현상을 제거하는 과정을 거친다.
9.1.2. 이상 현상의 종류
이상현상에는 삽입 이상(insertion error), 갱신 이상(update error), 삭제 이상(deletion error)이 있다.
종류 | 설명 |
---|---|
삽입 이상 | 새 데이터를 삽입하기 위해 불필요한 데이터도 함께 삽입해야 하는 문제 |
갱신 이상 | 중복 투플 중 일부만 변경하여 데이터가 불일치하게 되는 모순의 문제 |
삭제 이상 | 투플을 삭제하면 꼭 필요한 데이터까지 함께 삭제되는 데이터 손실의 문제 |
-
예시 다음 고객아이디와 이벤트번호 속성을 함께 사용하여 이벤트참여 릴레이션의 기본키를 구성한다.
-
삽입 이상
새로운 고객 데이터를 생성하기 위해서는 별도의 임의 이벤트번호를 발급해야한다. 아니면 이벤트 번호는 기본키 값이므로 NULL을 대입할 수 없어서 생성이 불가능하다.
-
갱신 이상
아이디가 apple인 고객의 등급이 gold에서 vip로 변경된다면, apple 고객에 대한 투플 3개의 등급 속성 값이 모두 수정되어야 한다.
-
삭제 이상
아이디가 orange인 고객의 데이터를 삭제하면 이벤트에 대한 정보뿐만 아니라, 해당 고객에 대한 정보인 고객아이디, 고객이름, 등급에 대한 정보도 삭제된다.
-
9.1.3. 정규화의 필요성
이상 현상이 발생하지 않도록, 정규화 과정을 통해 릴레이션을 관련이 있는 속성들로만 구성해야 한다. 따라서 정규화를 수행하기 위해서는 속성들 간의 관련성을 판단할 수 있어야 하고, 이러한 속성들 간의 관련셩을 함수적 종속성(Functional Dependency)이라고 한다.
9.2. 함수 종속
하나의 릴레이션을 구성하는 속성들의 부분집합을 X와 Y라 할 대, 어느 시점에서든 릴레이션 내의 모든 투플에서 X값에 대한 Y값이 항상 하나면 "X가 Y를 함수적으로 결정한다" 또는 "Y가 X에 함수적으로 종속되어 있다."
9.2.1. 함수 종속의 표현
함수 종속 관계는 X -> Y로 표현하고 X를 결정자, Y를 종속자라고 한다.
![9-6_함수_종속의_표현](/TIL/static/002ec772aa743b151019a0f5ce41989f/24c7e/9-6_%ED%95%A8%EC%88%98_%EC%A2%85%EC%86%8D%EC%9D%98_%ED%91%9C%ED%98%84.png)
9.2.2. 함수 종속의 종류
-
완전 함수 종속(FFD: Full Functional Dependency)
속성 집합 Y가 속성 집합 X에 함수적으로 종속되어 있지만, 속성 집합 X 전체에 종속된 것이지 일부분에 종속된 것이 아님을 의미한다. 일반적으로 함수 종속이라고 하면 완전 함수 종속을 의미한다. -
부분 함수 종속(PFD: Partial Functional Dependency)
속성 집합 Y가 속성 집합 X의 전체가 아닌 일부분에도 함수적으로 종속됨을 의미한다. 따라서 부분 함수 종속관계가 성립하려면 결정자가 여러 개의 속성들로 구성되어 있어야 한다. -
이행적 함수 종속(TFD: Transitive Functional Dependency)
X -> Y 와 Y -> Z 가 존재하여 논리적으로 X -> Z 가 성립할 때, Z가 X에 이행적으로 함수 종속되었다고 한다.
9.2.3. 릴레이션 예시
![9-10_릴레이션_예시](/TIL/static/7f9c8d4b96dec0b756eb32470d563039/bc962/9-10_%EB%A6%B4%EB%A0%88%EC%9D%B4%EC%85%98_%EC%98%88%EC%8B%9C.png)
이벤트 참여 릴레이션에서는 고객아이디가 고객이름을 유일하게 결정한다. 그리고 릴레이션의 기본키인 {고객아이디, 이벤트번호} 속성 집합은 당첨여부 속성을 유일하게 결정한다.
![9-11_함수_종속_표현_예시](/TIL/static/3d715cef18ad6a581edd42f313150e3c/e17e5/9-11_%ED%95%A8%EC%88%98_%EC%A2%85%EC%86%8D_%ED%91%9C%ED%98%84_%EC%98%88%EC%8B%9C.png)
![9-12_함수_종속_다이어그램_예시](/TIL/static/8392bc78c59ef1a15a3a0382b574354a/37e0d/9-12_%ED%95%A8%EC%88%98_%EC%A2%85%EC%86%8D_%EB%8B%A4%EC%9D%B4%EC%96%B4%EA%B7%B8%EB%9E%A8_%EC%98%88%EC%8B%9C.png)
9.3. 기본 정규형과 정규화 과정
9.3.1. 정규화의 개념과 정규형의 종류
함수 종속성을 이용하여 릴레이션을 연관성이 있는 속성들로만 구성되도록 분해해서, 이상현상이 발생하지 않는 올바른 릴레이션으로 만들어가는 과정을 정규화라고 한다.
릴레이션이 정규화된 정도는 정규형(NF: Normal form)으로 표현한다. 각 정규형마다 만족시켜야 하는 제약 조건이 다르고, 정규형의 차수가 높아질수록 요구되는 제약조건이 많아지고 엄격해진다. 하지만 모든 릴레이션이 제5정규형에 속해야 되는 것은 아니고, 릴레이션의 특성을 고려해서 적합한 정규형을 선택해야 한다.
![9-14_정규형의_종류](/TIL/static/4d3a58abeec1dfc90f012e9888923c2c/e7dce/9-14_%EC%A0%95%EA%B7%9C%ED%98%95%EC%9D%98_%EC%A2%85%EB%A5%98.png)
9.3.2. 제1정규형
릴레이션에 속한 모든 속성의 도메인이 원자 값으로만 구성되어 있다.
원자 값이라고 함은, 다중값을 가지지 않는 속성을 말한다. 하지만 제1정규형에 속한다고 하더라도 9.1.2 이상 현상의 종류와 같은 문제가 발생할 수 있다.
9.3.3. 제2정규형
릴레이션이 제1정규형에 속하고, 기본키가 아닌 모든 속성이 기본키에 완전 함수 종속된다.
제1정규형에서 부분 함수 종속을 제거하고 모든 속성이 기본키에 완전 함수 종속되도록 릴레이션을 분해하는 정규화 과정을 거쳐야 한다. 단 주의할 점은, 분해된 릴레이션들을 자연 조인하여 분해 전의 릴레이션으로 다시 복원할 수 있어야 한다. 이러한 정보의 손실 없는 릴레이션의 분해를 무손실 분해라고 한다.
![9-24_제2정규형](/TIL/static/616ba49cea097d241560f7f8d5779440/8c557/9-24_%EC%A0%9C2%EC%A0%95%EA%B7%9C%ED%98%95.png)
하지만 제2정규형도 이행적 함수 종속을 포함하고 있기 때문에 다음과 같은 이상현상이 발생한다.
![9-30_제2정규형_이상현상](/TIL/static/0c26eb85c31af94f1e1ad39ed1b457e1/8c557/9-30_%EC%A0%9C2%EC%A0%95%EA%B7%9C%ED%98%95_%EC%9D%B4%EC%83%81%ED%98%84%EC%83%81.png)
-
삽입 이상
할인율이 1%인 bronze등급이 생기더라도 해당 등급에 속하는 고객이 없으면 고객 릴레이션으로 삽입할 수 없다. -
갱신 이상
등급에 대한 할인율이 변경되면 해당 등급에 관련된 모든 투플에서 할인율 속성 값을 똑같이 변경해야 한다. 그렇지 않을 경우 데이터 불일치 문제가 발생한다. -
삭제 이상
고객 탈퇴로 인해 고객 릴레이션에서 투플이 삭제되면 등급과 할인율에 대한 정보까지 삭제된다.
9.3.4. 제3정규형
릴레이션이 제1정규형에 속하고, 기본키가 아닌 모든 속성이 기본키에 이행적 함수 종속되지 않는다.
릴레이션에서 이행적 함수 종속을 제거해서, 모든 속성이 기본키에 이행적 함수 종속이 되지 않도록 릴레이션을 분해하는 정규화 과정을 거쳐야 한다.
![9-32_제3정규형](/TIL/static/8ac7429499da58f6b2cd2c295341b9bf/80d71/9-32_%EC%A0%9C3%EC%A0%95%EA%B7%9C%ED%98%95.png)
9.3.5. 보이스/코드 정규형
릴레이션의 함수 종속 관계에서 모든 결정자가 후보키이면 보이스/코드 정규형에 속한다.
지금가지 살펴본 릴레이션들은 모두 후보키 속성이 하나밖에 없어서 이를 기본키로 선정하였다. 하지만 실제로는 하나의 릴레이션에 여러 개의 후보키가 존재할 수도 있는데, 이 경우에는 제3정규형까지 모두 만족하더라도 이상 현상이 발생할 수 있다. 따라서 후보키를 여러 개 가지고 있는 릴레이션에 발생할 수 있는 이상 현상을 해결하기 위해 제3정규형보다 좀 더 엄격한 제약조건을 제시한 것이 보이스/코드 정규형이다.
제3정규형에는 속하지만 보이스/코드 정규형에는 속하지 않는 릴레이션의 예를 통해, 후보키가 여러 개인 릴레이션에서 어떠한 이상 현상이 발생할 수 있는지를 알아보자. 아래 강좌신청 릴레이션에서는 한 고객이 인터넷강좌를 여러 개 신청할 수 있지만 동일한 인터넷 강좌를 여러 번 신청할 수는 없다. 그리고 강사 한 명이 인터넷강좌를 하나만 담당할 수 있고, 하나의 인터넷강좌는 여러 강사가 담당할 수 있다. 그러므로 투플이 구별할 수 있는 후보키로는 {고객아이디, 인터넷강좌}와 {고객아이디, 담당강사번호}가 있고, 이 중에서 {고객아이디, 인터넷강좌}를 기본키로 선정하였다.
![9-34_강좌신청_릴레이션](/TIL/static/b7ebfeea036851c468966a9455334795/3dd3e/9-34_%EA%B0%95%EC%A2%8C%EC%8B%A0%EC%B2%AD_%EB%A6%B4%EB%A0%88%EC%9D%B4%EC%85%98.png)
강좌신청 릴레이션에서 기본키인 {고객아이디, 인터넷강좌}가 담당강사번호 속성을 함수적을 결정한다. 그리고 강사 한 명이 인터넷강좌를 하나만 담당하므로 담당강사번호가 인터넷강좌를 함수적으로 결정한다고 볼 수 있다. 하지만 담당강사번호 속성이 후보키가 아님에도 인터넷강좌 속성을 결정하므로 강좌신청 릴레이션은 보이스/코드 정규형에 속하지 않는다.
![9-35_강좌신청_릴레이션_함수_종속_다이어그램](/TIL/static/ab88ff4357ddc52b45955ef268c191a9/7b439/9-35_%EA%B0%95%EC%A2%8C%EC%8B%A0%EC%B2%AD_%EB%A6%B4%EB%A0%88%EC%9D%B4%EC%85%98_%ED%95%A8%EC%88%98_%EC%A2%85%EC%86%8D_%EB%8B%A4%EC%9D%B4%EC%96%B4%EA%B7%B8%EB%9E%A8.png)
보이스/코드 정규형에 속하지 않는 강좌신청 릴레이션은 다음과 같은 이상현상이 발생할 수 있다.
![9-39_강좌신청_릴레이션_이상현상](/TIL/static/76ffd88aa29fae5d6119a7bd0d7a6f08/27524/9-39_%EA%B0%95%EC%A2%8C%EC%8B%A0%EC%B2%AD_%EB%A6%B4%EB%A0%88%EC%9D%B4%EC%85%98_%EC%9D%B4%EC%83%81%ED%98%84%EC%83%81.png)
-
삽입 이상
P005 강사가 중급토익 강좌를 담당하게 되었지만 이 강좌를 신청한 고객이 없다면, 이 내용을 강좌신청 릴레이션에 삽입할 수 없다.
-
갱신 이상
P004 강사가 담당하는 인터넷강좌가 중급토익으로 변경되면 P004 강사와 관련된 2개의 투플에서 인터넷강좌 속성의 값을 모두 중급토익으로 동일하게 변경해야 한다.
-
삭제 이상
고객아이디가 banana인 고객이 인터넷강좌 신청을 취소해서 해당 고객에 대한 투플을 삭제하면, P002강사가 기초토익 강좌를 담당하고 있다는 정보도 함께 삭제된다. 그런데 이 투플이 P002 강사에 대한 정보를 담고 있는 유일한 투플이라면 릴레이션에 P002 강사에 대한 데이터를 더는 유지할 수 없게 된다.
9.3.6. 제4정규형과 제5정규형
제4정규형은 릴레이션이 보이스/코드 정규형을 만족하면서, 함수 종속이 아닌 다치 종속(Multi Valued Dependency)를 가지지 않는다.
제5정규형은 릴레이션이 제4정규형을 만족하면서, 후보키를 통하지 않는 조인 종속(Join Dependency)을 가지지 않는다.
제5정규형을 만족할 때까지 분해하면 오히려 비효율적인 경우가 많기 때문에, 일반적으로는 제3정규형이나 보이스/코드 정규형에 속하도록 릴레이션을 분해한다.
9.3.7. 정규화 과정 정리
![9-42_정규화_과정](/TIL/static/ce97bcb66d8b07dcaf64ba7a1f4bde86/efc6e/9-42_%EC%A0%95%EA%B7%9C%ED%99%94_%EA%B3%BC%EC%A0%95.png)