이번 시간은 데이터베이스의 정규화에 대해 알아보려고 합니다. 개념을 대충 알고 있긴 했으나 용어가 나올 때마다 헷갈려서 이번 기회에 확실하게 정리하고 넘어가려고 합니다.
망나니 개발자 님이 정리해놓으신 정규화 블로그를 바탕으로 정리한 내용입니다. 설명드리는 예시도 해당 블로그에서 가져왔음을 참고해주세요.
데이터베이스에서 정규화는 데이터베이스 내의 데이터 구조를 조직화하고 최적화하는 과정을 의미합니다. 정규화의 기본 목적은 테이블 간에 중복된 데이터가 존재하지 않게끔 하는 것입니다.
중복된 데이터를 허용하지 않으면 데이터의 무결성을 유지할 수 있으며 DB의 저장 데이터 용량을 줄일 수 있습니다.
이러한 정규화를 단계별로 정의하고 있는데, 단계별로 어떤 방식으로 테이블을 분해하는지에 대해 알아보도록 하겠습니다.
데이터의 무결성이란 데이터의 라이프사이클동안 모든 데이터가 얼마나 완전하고, 일관되며, 정확한지를 나타내는 정도입니다.
제 1 정규화는 테이블의 컬럼이 원자값을 갖도록 테이블을 분해하는 것을 의미합니다. 즉, 테이블의 컬럼에서 값을 하나만 갖고 있도록 분해해주는 것입니다.
위의 테이블에서 추신수와 박세리는 여러 개의 취미를 가지고 있기 때문에 제 1 정규형을 위배하고 있습니다. 제 1 정규화를 통해 개선하면 아래와 같습니다.
제 2 정규화란 제 1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해하는 것을 뜻합니다.
완전 함수 종속은 기본키의 부분 집합이 결정자가 되어선 안된다는 것을 의미합니다.
예를 들어, 어떤 테이블에서 기본키가 두 개의 컬럼 A, B로 구성되어 있다고 가정했을 때, 다른 컬럼 C가 완전 함수 종속이 되려면 A와 B 두 컬럼을 모두 사용해서 C가 결정되어야 합니다.
만약 C가 A나 B 중 하나만으로도 결정될 수 있다면, 이는 완전 함수 종속이 아니라 부분 함수 종속을 의미합니다.
위의 테이블에서 기본키는 (학생번호, 강좌이름) 으로 복합키입니다. 그리고 (학생번호, 강좌이름)인 기본키는 성적을 결정하고 있습니다. 고로 성적 컬럼은 완전 함수 종속이 되고 있습니다.
그런데 강의실이라는 컬럼은 기본키의 부분 집합인 강좌이름에 의해 결정되고 있습니다. 즉, 결정자가 기본키의 부분 집합이기 때문에 아래와 같이 기존 테이블에서 강의실 컬럼을 분해하여 별도의 테이블로 관리하여 제 2 정규형을 만족시킬 수 있습니다.
제 3 정규화란 제 2 정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것을 의미합니다. 이행적 종속은 A -> B, B -> C가 성립할 때, A -> C가 성립되는 것을 의미합니다.
A가 B를 결정하고(B는 A에 종속), 동시에 B가 C를 결정한다면(C는 B에 종속), 이때 C는 A에 이행적으로 종속된다고 할 수 있고 A를 통해서 간접적으로 C가 결정되는 것입니다.
이행적 종속을 없애야하는 이유는 데이터 베이스에서 데이터 중복과 갱신 이상을 방지하기 위해서입니다. 만약 이행적 종속이 테이블 내에 존재한다면, 데이터를 갱신할 때 일관성 유지가 어려울 수 있습니다.
예를 들어, B의 값이 변경되면 C도 영향을 받기 때문에, 데이터를 수정할 때 추가적인 조치가 필요합니다. 제 3 정규화를 적용하여 이행적 종속을 해소하고 각 데이터가 기본키에만 종속되도록 하여 데이터의 독립성을 높이고 갱신 이상을 최소화 하도록 하는 것이 좋습니다.
위의 테이블에서 학생 번호는 강좌 이름을 결정하고 있고, 강좌 이름은 수강료를 결정하고 있습니다. 여기서 이행적 종속을 제거하기 위해 (학생 번호, 강좌 이름) 테이블과 (강좌 이름, 수강료) 테이블로 분해하여야 합니다.
예를 들어, 이행적 종속이 제거되지 않은 기존 테이블에서 501번 학생이 수강하는 강좌를 스포츠 경영학으로 변경할 시 수강료 또한 15000원으로 수정해줘야 합니다. 하지만 제 3 정규화를 통해 테이블을 분해하면 계절 수강 테이블에서 강좌이름만 바꿔주면 수강료에 대해선 변경할 필요가 없습니다.
BCNF 정규화란 제 3 정규화를 진행한 테이블에 대해 모든 결정자가 후보키가 되도록 테이블을 분해하는 것을 의미합니다. 즉, 각 속성이 오직 후보키에만 의존하도록 만드는 것입니다.
위의 특강수강 테이블에서 기본키는 (학생번호, 특강이름)입니다. 그리고 기본키는 교수를 결정하고 있습니다. 교수는 특강이름을 결정하고 있습니다.
여기서 교수가 특강이름을 결정하는 결정자이지만, 후보키는 아닙니다. 후보키는 각 행을 유일하게 식별할 수 있는 속성의 집합을 뜻하는데 교수가 학생 번호까지 결정하진 않기 때문에 후보키가 아닙니다.
그렇기 때문에 BCNF 정규화를 만족시키기 위해서 위의 테이블을 분해하여야 하고, 다음과 같이 특강신청 테이블과 특강교수 테이블로 분해할 수 있습니다.
이렇게 데이터 베이스의 정규화에 대해 알아보았습니다. 개념이 많이 생소했는데 망나니 개발자님의 블로그를 보면서 쉽게 이해할 수 있었습니다. ㅎㅎ
참고 자료
망나니 개발자님의 블로그