Functional Dependency란, 어떠한 값을 통해 종속 관계에 있는 다른 값을 유일하게 결정할 수 있음을 의미하는 것으로, 좋은 테이블 설계에 대한 정형적 기준이 된다. 마치 함수에서 하나의 x에 대응하는 y가 유일하게 결정되어야 한다는 이치와 비슷하기 때문에, 함수적 종속이라는 이름으로 불리게 되었다.
간단한 예시로, 나이와 생년월일 필드의 관계를 생각해볼 수 있다. 생년월일 필드의 값으로 나이가 결정되기 때문에 나이 필드는 생년월일 필드에 functional dependent하다. 이것은 기호로 "생년월일 → 나이"로 표기되며, 이 때의 생년월일을 Determinant(결정자), 나이를 Dependent(종속자)라고 말한다.
조금 더 실제와 가까운 예시를 들어보면 아래와 같다.
① SSN → Name
② Pnumber → {Pname, Plocation}
③ {SSN, Pnumber} → Hours
① Full Functional Dependency(완전 함수 종속)
② Partial Functional Dependency(부분 함수 종속)
③ Transitive Functional Dependency(이행적 함수 종속)
④ Determinant Functional Dependency(결정자 함수 종속)
관계형 데이터베이스의 설계에서 중복된 데이터가 최소화되도록 데이터베이스의 구조를 결정하는 것을 Normalization(정규화)이라고 한다. 다시 말해 서로 독립적인 관계는 별도의 테이블로 분해한다는 것이다. 당연히 정규화된 데이터베이스는 그렇지 않은 데이터베이스에 비해 더 효율적으로 연산을 수행한다.
데이터베이스의 Normalization 과정에서 Functional Dependency의 개념이 사용된다. 우리는 효율적인 데이터베이스를 설계하기 위해 Table에 오직 하나의 Funtional Dependency만 존재하도록 Normalization을 진행해야 한다.
① 1NF(1st normal form)
② 2NF(2nd normal form)
③ 3NF(3rd normal form)
④ BCNF(Boyce-Codd normal form)
물론, 제 4정규형과 제 5정규형도 존재는 하지만, 별로 실용적이지 않기 때문에 다루지 않을 것이다. 다만 제 4정규형은 Multi-valued Dependency 제거와, 제 5정규형은 Join Dependency 제거와 관련한다는 사실만 알아두자.
한 테이블에 FD가 하나만 존재해야 하는 이유에 대해 명확한 예시를 통해 알아보기로 하자.
① Employee와 Department에 대한 정보를 하나의 테이블에 표시한 경우
② Employee와 Project에 대한 정보를 하나의 테이블에 표시한 경우
오직 하나의 Funtional Dependency만 Table에 존재하도록 Normalization을 진행해야 한다고 했는데, 만약 2개 이상의 FD가 존재하는 상태로 Table을 방치하면 어떻게 될까?
위와 같이 하나의 테이블에 두 개 이상의 Entity의 속성이 혼합되는 경우, 아래와 같은 문제를 유발할 수 있다.
아래의 수강 테이블에서 발생할 수 있는 Anomaly에 대해 알아보자.
① Insertion Anomalies(삽입 이상)
② Deletion Anomalies(삭제 이상)
③ Modification Anomalies(수정 이상)
이와 같은 상황을 방지하기 위해선, attribute 간의 종속 관계를 분석하여 여러 개의 테이블로 분해하는 Normalization 과정이 필요하다.
Normalization을 위해 테이블을 분해하는 과정에서 Lossless Join 조건을 반드시 만족해야 한다. 이는 원래 테이블에서 분해된 여러 개의 테이블을 다시 join 했을 때, 원래의 테이블을 복원할 수 있어야 함을 의미한다. (사실 너무나 당연한 내용이다.)
Lossless Join 조건을 만족하지 않으면 join 연산을 수행할 때 원래 테이블에는 존재하지 않았던 Spurious(가짜) Tuple이 생길 수 있다(진짜 튜플과 구별하기 어려울 수도 있다). 따라서 테이블을 분해할 때에는 {기본키, 외래키}의 조합을 활용해야 한다.
1NF를 만족하기 위해서는 테이블의 모든 attribute가 오직 atomic value만 가져야 한다. 따라서 복합 속성, 다치 속성, 중첩 테이블과 같은 non-atomic value는 허용되지 않는다.
아래는 다치 속성을 갖는 테이블의 예시이다.
(a)와 (b)가 1NF를 만족하지 않는 이유는 Dlocation 필드가 다치 속성이기 때문이다. 이 테이블이 1NF를 만족하기 위해서는, 다치 속성을 각각의 튜플로 분리해야 한다. 이 과정을 가리켜 제 1 정규화라 하며, 그 결과는 (c)가 된다.
이번에는 아래의 중첩 테이블을 정규화하는 과정에 대해 알아보자. 아래는 Emp_Proj라는 메인 테이블 안에 Projs라는 서브 테이블이 중첩되어있는 형태이다.
위 테이블이 1NF를 만족하지 않는 이유는 다대다 관계를 가져야 할 테이블들이 하나의 테이블 안에 중첩되면서 redundancy가 발생하기 때문이다.
이처럼 한 사람이 여러 프로젝트에 참여하는 경우 데이터 중복이 심하게 발생하게 된다. 따라서 테이블을 아래와 같이 분해해야 한다.
여기서 테이블이 분해되더라도 기본키는 그대로인 것을 확인할 수 있는데, 이를 primary key propagation(key attribute를 제외하고는 redundancy가 없어야 함)이라 한다.
이와 같이 중첩 테이블은 중첩된 테이블을 분리하는 방식으로 1NF를 만족시킬 수 있다.
1NF를 만족하는 테이블에서는 더 이상 non-atomic value가 존재하지 않지만, 여전히 Anomaly는 발생한다. 대표적으로 아래와 같은 경우이다.
① Insertion Anomaly
② Deletion Anomaly
③ Modification Anmaly
분명 1NF를 만족함에도 불구하고 Anomaly가 발생하고 있는데, 이는 Partial FD가 존재하기 때문이다.
1NF의 Partial FD를 제거하여 2NF로 만들면, Anomaly를 어느 정도 해결할 수 있게 된다.
아래의 1NF 테이블을 2NF를 만족하도록 정규화해보자.
① FD1은 완전 함수 종속 관계이다.
② FD2, FD3는 부분 함수 종속 관계이다.
③ 테이블이 Full FD를 만족하도록 아래와 같이 분해한다.
이처럼 1NF를 만족하면서 Full FD로만 구성된 테이블은 2NF를 만족한다.
2NF를 만족하는 테이블에서도 Anomaly가 여전히 발생한다.
① Insertion Anomaly
② Deletion Anomaly
③ Modification Anomaly
2NF를 만족함에도 불구하고 Anomaly가 발생하는 이유는 Transitive FD가 존재하기 때문이다.
2NF의 Transitive FD를 제거하여 3NF로 만들면, Anomaly를 어느 정도 해결할 수 있게 된다.
위 테이블을 3NF를 만족하도록 정규화해보자. 3NF를 만족하려면 학번 → 지도교수 → 학과의 이행적 종속을 끊어야 한다.
① 이행적 종속을 끊는 방법은 Determinent를 pk로 사용하고, Dependent이면서 Determinent인 요소를 fk, pk로 사용하는 것이다.
② {학번(pk) / 지도교수(fk)}, {지도교수(pk) / 학과}와 같이 분해하면 이행적 종속이 끊어진다.
제 3 정규화까지 진행한 테이블에선 거의 Anomaly가 발생하지 않는다. 그럼에도 간혹 Anomaly가 발생할 수도 있다.
① Insertion Anomaly
② Deletion Anomaly
③ Modification Anmaly
3NF를 만족함에도 불구하고 Anomaly가 발생하는 이유는 Determinant FD가 존재하기 때문이다.
3NF의 Determinant FD를 제거하여 BCNF으로 만들면, Anomaly를 어느 정도 해결할 수 있게 된다.
위 테이블을 BCNF를 만족하도록 정규화해보자. BCNF를 만족하려면, 후보키가 아닌 Determinent를 pk와 fk로 사용해야 한다.
① 후보키가 아님에도 과목을 결정했던 교수를, pk로 하는 과목 교수 테이블을 만든다.
② 이후 학번과 교수를 복합 기본키로 하는 수강 교수 테이블을 만든다.
③ 이제 더 이상 후보키가 아닌 Determinent가 존재하지 않게 된다.
① 1NF를 만족하고 있는지 확인
② 2NF를 만족하고 있는지 확인
③ 3NF를 만족하고 있는지 확인
① 정규화를 만족하지 않는 테이블에 대하여..
② 주어진 Requirement를 분석하여 FD를 직접 찾아내는 문제