표준 SQL 및 데이터베이스 입문
여기부터는 조금 다른 관점의 정규화 이야기를 해봅시다. 이런 관점도 있다는 의미로서 소개하는 것으로 도메인키 정규형과 제6정규형입니다. 2가지 모두 제5정규형 다음 단계인 걸까요?
도메인키 정규형은 제5정규형 이후에 제안되었는데, 이는 지금까지의 정규형과는 약간 다른 관점에서의 정규화였기 때문에 6단계라고 느껴지지 않습니다. 하지만, 제5정규형 다음이라는 의믜로 제6정규형이라고 부르는 사람도 있습니다. 그리고 도메인키 정규형이 제안된지 20년이상 지난 후, 21세기에 들어와서 제안된 것이 바로 제6정규형입니다. 그래서 '제6정규형'이라는 명칭은 다소 혼란스럽다는 것입니다.
제3정규형 및 보이스코드 정규형, 그리고 제4정규형, 제5정규형까지 충족한 상태에서도 업데이트 불일치가 발생하는 경우가 있다는 점에서 새롭게 제안된 것이 도메인키 정규형과 제6정규형입니다.
도메인이라는 단어를 기억하십니까?
열에 들어갈 수 있는 값들의 집합을 말합니다. 예를 들어, 10단계 평가를 기록하는 열이라면, 그 도메인은 1부터 10까지의 정수입니다. 이처럼 도메인과 키에 주목한 정규형이 바로 '도메인키 정규형(Domain-Key Normal Form, DKNF)'입니다.
제2정규형부터 제5정규형까지는 함수종속에 주목하여 정규화를 수행했지만, 도메인키 정규형은 열이 취할 수 있는 값(도메인)에 초점을 맞춰 정규화를 진행합니다. 앞에서 사용했던 상품/공급업체/창고 테이블을 다시 한번 봅시다. 이 테이블에서는 상품-공급업체, 상품-창고라는 2개의 다치종속이 있었기 때문에, 우선 상품/공급업체 테이블과 상품/창고 테이블로 분할되었습니다.(제4정규형) 하지만, 이 두 테이블을 조인하여 원래의 표를 복원하려고 하면 노이즈가 발생하는 것이 확인되었습니다. 그래서 새롭게 공급업체/창고라는 테이블을 추가했습니다. (제5정규형)
이제 '원래 테이블'을 또 다른 관점에서 살펴봅시다.
우선 (상품, 공급업체 창고)라는 조합은 하나의 사실입니다. 따라서 이것을 분해할 수는 없습니다. 또한, 상품의 납품처가 결정되어 있다면 (상품, 공급업체)도 하나의 사실이 됩니다. 그리고 (상품, 공급업체)라는 조합이 올바르다면, (상품, 공급업체, 창고)라는 조합도 올바른 것으로 간주할 수 있습니다.
그래서 (상품, 공급업체)라는 테이블과 (상품, 공급업체, 창조)라는 테이블을 생성하고, (상품, 공급업체)를 외부키로 사용합니다. 이번 사례에서는 참조제약에 의해 값의 모순은 방지되더라도, 상품과 공급업체 간의 관계가 여러 테이블에 걸쳐 존재하게 됩니다. 이와 같이, 도메인키 정규형의 테이블은 겉보기에는 제2정규형이나 제3정규형의 형태가 아닌 것으로 보일 수 있습니다. 또한, 참조제약이 많이 존재하는 경우, 업데이트 처리의 부담이 커지는 문제도 발생할 수 있습니다.
제6정규형은 어느 의미에서는 깔끔합니다. 식별자로부터 결정할 수 있는 값이 최대 1개가 되도록 하는 정규형입니다. 어떻게 된다는 뜻일까요?
키 외의 열은 최대 한개만 존재하도록 하는 것입니다. 예를 들어, '직원코드와 소속부서, 직위'라는 테이블이 있다고 가정해 봅시다.
소속부서와 직위가 각각 한개씩이라면, 지금까지의 정규형으로는 이 테이블에 특별한 문제가 없을 것입니다. 즉, 직원코드를 알면 그 사람의 소속부서와 직위를 모두 알 수 있으니 문제가 없어 보입니다.
하지만, 이것을 직원코드와 소속부서, 직원코드와 직위의 2개의 테이블로 분리하는 것이 제6정규형입니다. 예를 들어, 새 사원의 부서를 결정했는데, 그 사원이 일반사원인지 과정인지 결정되지 않으면 직위가 NULL이 되어버릴 수 있습니다. 이런 문제를 제거할 수 있는 것이 제6정규형입니다.
도메인과 키에 초점을 맞추고 정규화
키 이외의 열은 최대 1개라는 것입니다. 그러면 테이블이 엄청 많이 늘어나지 않을까요? 늘어납니다.
결합으로 만들어질 수 있는 관계가 존재하지 않는 형태를 '제6정규형(6th Normal Form, 6NF)'이라고 합니다. 제6정규화를 적용한 테이블은 식별자만 있거나, 식별자와 속성(열)이 단 하나만 있는 형태가 됩니다.
예를 들어, (직원코드, 소속부서, 직위)라는 테이블은 직원코드를 알면 소속부서와 직위를 알 수 있지만, 제6정규형에서는 이 테이블을 (직원코드, 소속부서)와 (직원코드, 직위)라는 2개의 테이블로 분해하여 결합한 결과로 간주합니다.
이와같이, 소위 '암묵적 JOIN'이 필요없도록 테이블을 분할하는 것이 제6정규형입니다. 물론, 이는 무손실 분해(lossless decomposition)여야 하며, 즉 조인을 통해 원래의 데이터를 복원할 수 있어야 합니다. 식별만 있거나, 식별자와 속성 한개만 있는 테이블은 변경이력을 추적하기에 용이하다는 장점이 있습니다. 시계열 데이터처럼 시간이 지남에 따라 추적할 필요가 있는 경우에는 제6정규형이 유용합니다. 또한 제6정규형으로 분해된 테이블에는 NULL값이 발생하지 않습니다.
NULL은 원래 한 테이블에 시간에 따라 결정되는 항목이나, 구조가 다른 데이터를 함께 관리할 때 발생하는데 제6정규형에서는 각각 별도의 테이블로 관리되므로 NULL이 존재하지 않습니다. 한편 제6정규형을 적용하면 데이터를 표시할 때 결합(조인) 작업이 많이 발생하여 성능저하되는 문제가 있습니다. 이 때문에 일반적인 테이블에서는 보통 제6정규형을 적용하지 않습니다. (살짝 현실적이지 못한 정규형이라고 봐도 됩니다)
물론 필요한 경우도 있겠지만, 결국 어디까지 할지는 상황에 따라 결정되는 문제입니다. 그래서 보통 정규화는 제3정규형과 보이스코드 정규형까지 더 진행한다고 해도 제5정규형까지 수행하는 것이 일반적입니다. 다만, 이런 관점에서도 정규화를 고려할 수 있다는 것을 보여주는 것입니다.
©2024-2025 GAEBAL AI, Hand-crafted & made with Damon Jaewoo Kim.
GAEBAL AI 개발사: https://gaebalai.com
AI 강의 및 개발, 컨설팅 문의: https://talk.naver.com/ct/w5umt5