표준 SQL 및 데이터베이스 입문
데이터를 제1정규형으로 정규화했으므로, 드디어 관계형 데이터베이스 관리할 수 있는 상태가 되었습니다. 하지만 이것만으로는 충분하지 않습니다. 다음으로 함수종속에 기반한 정규형을 설명합니다.
함수종속이란 무엇인가?
예를 들어, 학적코드가 '001'이면 성명은 '이순신'과 같이 한 항목의 값이 결정되면 다른 항목의 값도 결정되는 관계를 함수종속이라고 합니다. 즉, 이름은 학적코드에 항수종속한다고 표현할 수 있습니다.
또한, 키에 의해 결정되는 항목은 '종속 속성(dependent attribute)'이라고도 불립니다. 예를 들어, 이름은 학적코드의 종속속성이 되는 것입니다. 약간은 어렵지만, 용어를 익히면 다른 사람과 이야기할 때나 책을 읽을 때 도움이 됩니다.
제1정규형 이후에는 함수종속에 주목한 정규형들이 있는데, 대표적으로 제2정규형, 제3정규형, 그리고 보이스코드 정규형(BC 정규형)이 있습니다. 종속(dependency)이란 항목들(열과 열 사이)의 의존관계를 말하며, 특히 'A가 결정되면 X가 결정된다'는 관계를 '항수종속(functional dependency, DF)'이라고 합니다. 예를 들어, 학생번호에 의해 이름이 결정된다면 '이름은 학생번호에 함수 종속한다'라고 표현합니다.
제2정규형, 제3정규형, 보이스코드 정규형의 최종목표는 '모든 열이 주키(primarty key)에 의해 결정되는' 상태를 만드는 것입니다.
제2정규형, 제3정규형, BC정규형의 목표
종속관계는 '{A} ⇒ X'와 같이 표현할 수 있습니다. 만약, 복합키인 A와 B로부터 X가 결정된다면, '{A, B} ⇒ X'라고 표현합니다. 이번에는 A, B, X라는 열이 있는 테이블을 '(A, B, X)'로 표기하며, 이때 A가 주키인 경우 '({A}, B, X)'로 A와 B의 복합키가 주키인 경우는 '({A, B}, X)'로 표기합니다.
제2정규형 이후는 표의 형태로 보이더라도, 관계형, 즉 열과 열 사이의 관계에 주목하여 같은 테이블에 있으면 발생할 수 있는 문제를 해결하기 위해 여러 테이블로 분할하거나 테이블의 수를 늘리는 방식으로 처리합니다. 또한 테이블이 늘어나게 됩니다.
이때, 원래의 테이블로 복원할 수 있는지가 중요합니다. 잘 모르겠다면 테스트 데이터 등으로 간단히 시도해 보는 것을 추천합니다.
SELECT문은 조금밖에 몰라도 JOIN만 사용하면 되므로 문제가 없습니다.
제 2정규형 이후로 정규화에 따라 테입르이 여러개로 분리됩니다. 적절하게 분할했다면 SELECT문에서 JOIN을 사용하여 원래의 데이터를 다시 표시할 수 있어야 하지만, 항목을 부적절하게 분리하면 데이터가 누락되거나 반대로 중복되어 나타날 수 있습니다. 특히, 복합키와 관련된 정규화에서 분할 후의 테이블에 외부키가 부족할 경우 문제가 발생하므로, 반드시 테스트 데이터를 통해 확인해야 합니다. 테이블은 분할해도 정보가 손실되지 않는 상태를 '무손실분해(lossless join decomposition)'라고 합니다.
함수종속에 따른 정규화에도 여러 형태가 있습니다. 처음에 고려되었던 것은 제2정규형과 제3정규형 2가지였고, 그 후, 제3정규형을 더욱 엄격하게 만든 보이스코드 정규형이 추가되었습니다.
각각 별도의 작업일까요?
설명은 순차적으로 진행하겠지만, 자신의 데이터를 정규할 때는 3가지를 구분하지 않고 '함수종속이 숨어있지 않은가?'정도로 판단하면 됩니다.
복합키의 일부에 함수 종속되는 것을 '부분 함수 종속(partial functional dependency)'이라고 합니다. 예를 들어, A, B, C, D라는 열이 있는 테이블에서 A와 B의 복합키에 대해 {A, B} ⇒ C, {A, B} ⇒ D라는 종속관계가 있다고 가정합시다. 이때, 실제로 D가 A와 B의 조합이 아니라 A에 의해서만 결정된다면, D는 복합키 {A, B}에 부분적으로 종속되어 있다고 할 수 있습니다.
부분함수 종속 종속성
제1정규형으로부터 부분함수 종속을 제거한 형태를 제2정규형(2nd Normal Form, 2NF)라고 합니다.
부분함수 종속을 제거하고 제2정규형 만들기
함수종속된 항목이 키 전체에만 종속되어 있는 것을 (부분함수 종속이 아닌 것을) '완전함수 종속(full functional dependency)'이라고 합니다. 제2정규형은 '키 이외의 모든 항목이 키에 완전함수 종속되어 있는 형태'라고도 할 수 있습니다.
다음은 제3정규형입니다. 전이적 함수종속(transitive functional dependency)를 제거하는 단계입니다. 예를 들어, A, B, C라는 열이 있는 테이블에서 {A} ⇒ B, {A} ⇒ C라는 관계외에도 {B} ⇒ C라는 관계가 있다고 합시다. 이 경우, {A} ⇒ B와 {B} ⇒ C로부터 {A} ⇒ C가 도출될 수 있습니다. 이러한 관계를 전이적 함수 종속이라고 합니다.
제2정규형 이후, 키에 대한 전이적 함수종속을 제거한 형태가 제3정규형(3rd Normal Form, 3NF)입니다. 예를 들어, 학적코드를 주키로 하는 테이블에 전공과목과 교관이라는 항목이 있다고 합시다. 학적코드 001의 전공과목은 'xx', 담당교사는 'OO'라는 관계를 나타내는 테이블에서 만약, 과목과 담당교사 사이에 종속관계, 즉, 과목이 결정되면 교관도 결정되는 관계가 있으면, {학적코드} ⇒ 전공과목, {과목} ⇒ 담당교사와 같이 표현됩니다. 이 경우, 학적번호와 교관이 전이적 함수종속 관계에 있다는 것을 알 수 있습니다.
전이적 함수 종속성을 제거하고 제3정규형으로 만들기
원래 테이블(제3정규형되지 않은 테이블)에서는 학적코드가 결정되지 않으면 과목과 담당교사의 조합 데이터를 등록할 수 없습니다.(입력 불일치) 또한 그만둔 학생의 행을 삭제하면 과목과 담당교사 간의 관계까지 삭제될 위험이 있습니다. (삭제 불일치)
제3정규형은 키가 아닌 항목들끼리 서로 독립적인 형태, 즉, '키 이외의 항목들은 키에만 종속하며, 키가 아닌 항목을 변경해도 다른 키가 아닌 항목에는 영향을 주지 않는다'라는 것을 의미합니다. 정규화 후의 왼쪽 테이블에서는 성명과 전공과목이 각각 학적코드에 종속되어 있으므로, 학적코드를 특정하면 그것만으로 성명과 전공과목을 알 수 있습니다. 또한, 전공과목을 변경해도 성명에는 영향을 주지 않습니다. 오른쪽 테이블은 열이 두개인데, 전공과목을 특정하면 담당교사를 알 수 있는 상태입니다. 따라서 이 테이블은 제3정규형을 충족합니다.
보이스코드 정규형은 제3정규형에 대해 '아직 전이적 함수종속이 남아 있다'는 발견에서 만들어진 정규형입니다. 제3정규형이어도 전이적 함수종속이 남아 있는 경우가 있습니다. 제3정규형에서는 키에 대한 전이적 함수종속은 제거했지만, '키이면서 동시에 다른 항목에 함수 종속되는' 항목은 완전히 제거되지 않았습니다.
제3정규형을 충족한 상태에서 키 이외의 항목이나 복합키의 일부로부터 키를 구성하는 항목에 대한 함수 종속성을 제거한 형태를 '보이스코드 정규형(Boyce-codd Normal Form, BCNF)'이라고 합니다.
예를 들어, ({A, B}, C, D)라는 테이블에서 {C} ⇒ A나 {D} ⇒ A와 같은 관계를 없앤 형태입니다.
모든 전이적 함수 종속을 제거하고 보이스코드 정규형으로 만들기
함수 종속에도 여러가지 패턴이 있다는 것을 알게 되었을 것입니다. 실제로 설계시, 종속의 종류까지 신경 쓸 필요는 없지만, 제2정규형의 관점, 제3정규형의 관점등을 지표로 삼아 확인하면 놓치는 부분을 방지할 수 있습니다.
제2정규형, 제3정규형, 보이스코드 정규형을 정리하면 아래와 같습니다.
제2정규형부터 보이스코드 정규형까지는 함수종속에 주목한 정규형입니다. 'X에 의해 Y가 결정된다'는 관계가 있을 때, ① X가 키인지, ② X만이 키인지를 주의해야 합니다. 또한, X가 키일 때, X에 종속되지 않는 속성이 없는지도 확인해야 합니다.
정규화되었는지 여부를 확인할 때 체크포인트
이로써 정규화의 두번째 단계가 끝났습니다. 일반적으로 관계형 데이터베이스를 사용할 때는 이 정도까지 정규화되어 있으면 좋다고 봅니다.
©2024-2025 GAEBAL AI, Hand-crafted & made with Damon Jaewoo Kim.
GAEBAL AI 개발사: https://gaebalai.com
AI 강의 및 개발, 컨설팅 문의: https://talk.naver.com/ct/w5umt5