#title 정규화 정리 [[TableOfContents]] ==== 현상들 ==== OLTP시스템에서 다음의 현상이 발생하는가? * 대부분의 프로시저가 복잡하다. * 성능 문제가 심각하다. * 'oo로그'라는 로그 테이블들이 많이 존재한다. 이 현상들은 3차 or 보이스-코드 정규화의 개념이 들어가지 않은 데이터베이스에서 쉽게 볼 수 있는 현상들이다. 알다시피 문제의 원인을 해결하지 않는 이상은 눈에 비춰진 현상을 없애는 것에 한계가 존재한다. 그래서 시스템의 한계를 늘려주는 하드웨어 증설과 같은 방법으로 감가상각을 쳐서 0원이 될 때까지 버티기 작업으로 위태로운 생활을 이어간다. ==== 현상들에 대한 원인은? ==== 문제의 원인은 데이터의 중복에 있다. 애시당초 데이터의 중복이 될 수 밖에 없는 구조로 설계를 한 것이 문제다. '데이터의 중복이 될 수 밖에 없는 구조로 설계'는 하나의 릴레이션(테이블)에 2가지 이상의 주제를 포함하고 있는 것을 말한다. 릴레이션은 2차원 구조이고, 각 셀에 해당하는 값은 원자값으로 아주 단순한 의미를 가지게 된다. 관계형 모델은 1가지의 주제만으로 벅찬 구조인데, 2가지 이상의 주제를 하나의 테이블에 표현하려니 복잡해질 수 밖에 없다. 복잡성의 증가는 유연성과 성능을 저하 현상으로 우리의 눈에 보이게 된다. 예를 들어, 릴레이션 R에 A,B 이렇게 2개의 주제를 표현했다고 가정해보자. 만약 B주제가 변경되었다면 릴레이션 R을 변경해야 한다. 이 변경은 단순한 변경이 아니다. 릴레이션 R에는 B주제 뿐만 아니라 A주제도 있다. 그러므로 B주제의 변화에 대해 A주제가 얼마나 영향을 받는지에 대한 고려도 필요하게 된다. 또한 릴레이션 R에 관련된 SQL이나 프로시저도 모두 점검하고 변경해줘야 한다. 또한 여러가지 이상현상(삽입이상, 삭제이상, 갱신이상)이 발생하여 이를 땜빵하기 위한 여러 땜빵용 테이블과 복잡한 로직이 만들어지게 된다. 그 결과로 약한 응집력과 강한 결합도를 가진 시스템이 되어 버린다. 한 부분을 변경하는데 시스템의 여기 저기를 모두 뜯어 고쳐야 하는 것은 변화에 취약함과 복잡함을 의미한다. 복잡하다는 것은 시스템이 처리해야 할 일이 많음을 의미하며 이는 시스템의 자원을 많이 사용해야 함을 뜻한다. 즉, 변화에 대한 늦은 대응과 성능저하로 우리의 눈에 비치게 된다. 결국은 라이프 사이클 동안에 전체적인 비용증가를 가져온다. 만약, 릴레이션R1에 A주제, 릴레이션R2에 B주제의 데이터를 담고 있다면 어떨까? 당연히 관련된 부분만 살짝 변경해주면 된다. 이렇게 되면 모델도 단순해져 전체적인 유지보수 비용을 떨어뜨리게 된다. 결론은? 정규화를 해야 한다는 것이다. 정규화는 유연성과 성능 문제를 해결하는 최고의 솔루션이다. ==== 함수종속과 키(key) ==== x값을 알 수 있을 때 y의 값도 알 수 있으면, y는 x에 함수적으로 종속되어 있다고 말한다. 이를 x -> y 로 표시하고, x를 결정자, y를 종속자라고 말한다. 키는 릴레이션의 각 인스턴스를 식별할 수 있는 속성 또는 속성들을 말한다. ==== 2차 정규화 ==== 다음의 릴레이션을 보자. ||학생번호||특별활동||특별활동비|| ||100 ||스키 ||200 || ||100 ||수영 ||50 || ||175 ||탁구 ||50 || ||200 ||수영 ||50 || ||100 ||골프 ||65 || * 키 : 학생번호 + 특별활동 * 함수종속 : 특별활동 -> 특별활동비 * "특별활동비"는 "특별활동"에 종속되고, 릴레이션의 키(학생번호 + 특별활동)에 부분종속(partially dependent)된다. 다음과 같이 분리하면 2차 정규형이 된다. ||학생번호||특별활동|| ||100 ||스키 || ||100 ||수영 || ||175 ||탁구 || ||200 ||수영 || ||100 ||골프 || ||특별활동||특별활동비|| ||스키 ||200 || ||수영 ||50 || ||탁구 ||50 || ||골프 ||65 || 2차 정규화 정리 * 키가 단일속성이면 모든 릴레이션은 2차 정규형이다. * 2차 정규형은 복합키를 가진 릴레이션에 대해서만 따져보면 된다. ==== 3차 정규화 ==== 3차 정규형은 2차 정규형이면서 이행종속(transitive denpendent)이 없는 릴레이션을 말한다. 이행종속이란 릴레이션R 에 속성 A,B,C가 있다면 C를 알기 위해서 B를 통해 간접적으로 알 수 있는 종속(A->B->C)을 말한다. 2차 정규화에서 쓰인 릴레이션에서 "한명의 학생은 단 하나의 특별활동만 할 수 있다"는 제약조건이 있다는 가정을 해보자. ||학생번호||특별활동||특별활동비|| ||100 ||스키 ||200 || ||175 ||탁구 ||50 || ||200 ||스키 ||200 || ||300 ||골프 ||65 || ||400 ||골프 ||65 || * 키 : 학생번호 * 함수종속 : * 학생번호 -> 특별활동 * 특별활동 -> 특별활동비 * 이행종속 : 학생번호 -> 특별활동 -> 특별활동비 함수적 종속을 말로 풀어보면 다음과 같을 것이다. * 어떤 "학생번호"가 어떤 "특별활동"을 하는가를 알기 위해서는 "학생번호"만 알면 알아낼 수 있다. * 어떤 "특별활동"에 얼만큼의 "특별활동비"가 필요한가를 알기 위해서는 "특별활동"만 알면 알아낼 수 있다. * 어떤 "학생번호"의 "특별활동비"를 알기 위해서는 해당되는 "학생번호"의 "특별활동"을 알아낸 후 그 특별활동의 "특별활동비"를 알아내면 된다. (이행종속). 학생번호 100의 특별활동비는 학생번호가 10인 학생이 어떤 특별활동을 하는지 알아야 내야만 얼마인지 알아 낼 수 있다. 이행종속을 제거하면 다음과 같이 3차 정규형이 된다. ||학생번호||특별활동|| ||100 ||스키 || ||175 ||탁구 || ||200 ||스키 || ||300 ||골프 || ||400 ||골프 || ||특별활동||특별활동비|| ||스키 ||200 || ||탁구 ||50 || ||골프 ||65 || ==== 보이스-코드 정규화 ==== 보이스-코드 정규형은 3차 정규형이면서 모든 결정자가 후보키인 릴레이션을 말한다. 다음의 릴레이션을 보자. 이 릴레이션에는 "각각의 특별활동에는 단 1명의 코치만 있다"는 제약조건이 있다. ||학생번호||특별활동||코치|| ||100 ||스키 ||하정우|| ||100 ||수영 ||김태환|| ||175 ||탁구 ||현정화|| ||200 ||수영 ||이재학|| ||100 ||골프 ||박세리|| ||300 ||수영 ||이재학|| * 후보키 * 학생번호 + 특별활동 * 학생번호 + 코치 * 함수종속 * 종속1: (학생번호 + 특별활동) -> 코치 * 종속2: (학생번호 + 코치) -> 특별활동 * 종속3: 코치 -> 특별활동 (후보키가 아니다!!) 종속1, 종속2는 결정자가 후보키다. 하지만 종속3의 결정자는 후보키가 아니다. 그러므로 보이스-코드 정규화를 하면 다음과 같은 릴레이션들이 된다. ||학생번호||코치|| ||100 ||하정우|| ||100 ||김태환|| ||175 ||현정화|| ||200 ||이재학|| ||100 ||박세리|| ||300 ||이재학|| ||코치 ||특별활동|| ||하정우||스키 || ||김태환||수영 || ||현정화||탁구 || ||이재학||수영 || ||박세리||골프 || ==== 4정규화 ==== 4차 정규형은 보이스-코드 정규형이면서, 다치종속(multi-value dependent)가 없는 릴레이션을 말한다. 다치종속이란 하나의 값이 여러 값을 결정하는 것을 말한다. "->>"과 같이 표기한다. 이 릴레이션에는 한 학생이 여러 특별활동을 할 수 있고, 복수전공이 가능하다는 제약조건이 있다. ||학생번호||특별활동||전공|| ||100 ||스키 ||경영|| ||100 ||수영 ||경영|| ||100 ||스키 ||컴공|| ||100 ||수영 ||컴공|| ||200 ||골프 ||수학|| ||300 ||수영 ||음악|| * 키 : 학생번호 + 특별활동 + 전공 * 다치종속 * 학생번호 ->> 특별활동|전공 (한 명의 학생이 여러개의 특별활동, 한 명의 학생이 여러 개의 전공) 다치종속을 없애어 4차 정규화를 하면 다음과 같이 된다. ||학생번호||특별활동|| ||100 ||스키 || ||100 ||수영 || ||200 ||골프 || ||300 ||수영 || ||학생번호||전공|| ||100 ||경영|| ||100 ||컴공|| ||200 ||수학|| ||300 ||음악|| 이런 현상이 발생하는 이유는 관계(relationship)이 제대로 파악되지 않았기 때문이다. 또한 어떤 학생이 어떤 특별활동과 어떤 전공을 하는 지에 2가지의 주제를 하나의 릴레이션에 포함했기 때문에 발생한 현상이다. 그림으로 표현하면 다음과 같다. 3원관계(3진관계)를 제거하라고 모델링 책에서 떠드는 이유가 다치종속 때문이기도 하다. attachment:정규화정리/norm01.jpg 흔한 경우는 아니지만, "특별활동"과 "전공"도 관계를 가진다면, 3원관계를 그대로 둬도 괜찮지만, 5차 정규화의 이슈가 있다. 그러므로 3원 관계는 3개의 릴레이션의 관계를 따져보고 2원관계로 만들어주는 것이 속 편하다. 2원 관계로 만들다보면 자연스럽게 "특별활동"과 "전공"이 엮일 업무적인 이유를 찾지 못해서 자연스러운 4차 정규형이 될 것이다. ==== 격언 ==== 소프트웨어 분야에는 다음과 같은 오래된 격언이 있다. * 결합도는 낮추고 응집도는 높여라. * 정보 교환이 자주 발생하는 영역들은 나누지 말라. 이는 정규화와 비정규화의 기준이 될 수 있다.