데이터 모델링을 왜 낭떠러지에 버려두는가?

일반입력 :2003/08/14 00:00

김형태

필자가 처음 IT 산업에 입문했을 때 50GB 정도의 데이터를 가진 프로젝트는 매우 대용량의 시스템을 구축하는 것이었다. 하지만 현재 50GB 정도는 개인용 컴퓨터에서도 적은 용량이 되었고, 대부분의 프로젝트들이 테라바이트 급의 데이터를 다루고 있다. 그러나 필자가 IT에 입문하였던 17년 전과 현재를 비교해보면 개발 기술(특히 개발 언어 및 개발 방법론)은 비약적인 발전을 해오고 있는 것에 반하여 ‘데이터를 어떻게 저장하고 이를 어떻게 효율적으로 사용할 수 있도록 할 것인가’라는 즉, 데이터 모델링 분야에 있어서는 뜻밖에도 소홀히 다루어지고 있다는데 놀라지 않을 수 없다.그럼 무엇이 문제인가? 외국도 우리와 같은 상황인지 의문이 생기지 않을 수 없다. 필자가 그간의 경험에 비추어보면 개발자는 넘쳐 나도 어느 정도의 수준을 갖춘 데이터 모델러를 만나기란 무척 어려운 것이 현실이었다. 그럼 데이터 모델러를 찾기가 어려운 이유는 무엇인가? IT 선진국에서도 이런 상황은 마찬가지이며, 우리나라 또한 프로그래밍 개발 기술을 가르치는 교육은 많아도 데이터 모델링을 체계적으로 가르치는 곳은 그리 많지 않다. 기껏 프로젝트에서 사용하기로 한 데이터 모델링 툴을 통하여 어떻게 ERD(Entity Relation Diagram)를 그리는가 하는 작도법(데이터 모델은 최종 결과물로 사용할 ERD를 그리는 것이 아니라 비즈니스의 모든 요구사항이 엔티티와 릴레이션으로 함축 표현되어 개발 및 유지보수 시에 사용할 데이터 바이블이 되어야 하며 이를 모델링하기 위한 과정의 도구이지 결과물을 위한 도구가 아니다)을 가르쳐 주는 수준으로 남이 만들어 놓은 데이터 모델을 읽어볼 수 있는 수준밖에는 배울 수 없다.데이터 모델링, 정말 중요한가?그럼 왜 데이터 모델링의 상세한 것을 가르쳐 주지 않는가? 독자들도 ‘엔티티가 무엇이냐’는 정의를 여러 서적을 통하여 얻고자 노력해 본 적이 있을 것이다. 보통의 많은 서적들이 ‘관리하여 할 중요한 것(Things of importance)’과 같이 매우 애매모호한 답만을 주고 있다. 필자도 처음에 데이터 모델링을 공부했을 때 이와 같은 정의를 보고 매우 황당해 한 적이 있다. 아마 독자들도 마찬가지였을 것이다. 이렇듯 엔티티의 정의조차 애매모호한 상황에서 데이터 모델을 어떻게 만들 것인가 참으로 막막한 일이 아닐 수 없다. 예를 들어 어느 회사에나 있는 ‘고객’이라는 엔티티를 모델러가 ERD에 그려 놓았다. 그리고 이에 대해 이 집합이 우리 회사와 한 번이라도 계약을 하였던 사람들의 집합인지 아니면 우리나라 모든 사람을 의미하는 것인지 혹은 외국인은 포함되어 있는지, 이것이 개인과 법인을 포함하고 있는 것인지, 그럼 이들의 개체는 무엇으로 구분할 수 있으며 개체의 생명주기는 어떻게 되는지 등 몇 가지만 질문하여도 정확한 대답은 나오지 않는 것이 현실이다. 모델러는 하나의 엔티티를 정의하면서 명확하게 집합을 정의해 주어야 하며 미래에 발생 가능한 집합까지도 예상하여 정의해야 한다. 이러한 집합의 본질을 찾아내는 것이 어렵다고 외면한다면 만들고 있는 시스템이 존재하는 한 프로그래머들에게 두고두고 원성을 듣게 될 것이다. 비즈니스 규칙은 세월이 지나감에 따라 자주 변화하지만 비즈니스 속에 들어 있는 주요 속성들의 본질은 잘 변화하지 않는다. 그러므로 개체의 본질을 잘 정의한 데이터 모델은 향후 확장성 및 유연성을 두루 갖춘 시스템으로 만들어질 수 있다. 이렇듯이 데이터 모델링이란 정답이 없는 모호한 것이 아니라 객관화를 하지 못하기 때문에 아마도 많은 사람들이 어려워하며, 구축하는 시스템마다 그것들의 정의가 달라지기에 제대로 된 서적이나 교육 프로그램들이 없지 않나 생각된다. 필자는 우리의 데이터 모델링 현주소를 집어보고 비효율적인 데이터 모델링이 미치는 영향을 몇 가지의 예를 통하여 살펴봄으로써 데이터 모델링의 중요성을 독자들에게 강조하고자 한다.  데이터 모델링의 암울한 현주소대개의 경우 프로그래머가 그 업무에 대한 이해가 조금 깊어지면 그 시스템의 데이터 모델을 담당하게 된다. 그 보다도 열악한 경우는 전산 경험이 몇 년 되지도 않는 초년병 프로그래머가 업무에 대한 지식조차도 없는 상태에서 데이터 모델링을 담당한다. 데이터 모델링이란 어떻게 하는 것인지 선배들조차 가르쳐주는 일이 없고 선배들도 프로그래밍에만 익숙해 온 탓에 이들의 머리 속에는 온통 프로그램 로직(LOOP 및 IF THEN ELSE 처리)만 가득하다 보니 집합을 명확히 정의하는 것에는 소홀하며 오직 프로그램 처리 프로세스에 맞춘 데이터 모델이 양산되는 결과를 초래하고 만다(데이터 모델링이란 프로그램 로직과는 독립적으로 이루어져야 함에도 불구하고 말이다). 뒤에서 ‘데이터 모델링의 잘못된 유형’이란 제목으로 다시 다루겠지만 비즈니스 로직은 시장 환경에 따라 자주 변경되고 이 경우 프로그램 처리에 맞춘 데이터 모델은 전면적인 수정이 발생하지 않을 수 없다. 또한 많은 중복 데이터를 만들어 데이터의 일관성 관리를 어렵게 하며 필요 없는 데이터를 관리하게 한다.개발자야 모델러야 누가 잘못한거야?그렇다면 이러한 애매모호한 데이터 모델을 가지고 개발자는 프로그램을 어떻게 작성할까? ERD도 없이 달랑 테이블과 속성명 및 속성의 길이나 타입만 나와 있는 문서만을 가지고 과연 어떻게 프로그램을 작성할 것인가(필자도 늘 이것이 매우 궁금하였다. 정말 대단한 프로그래머들이라 할 수 있다)? 어떻게 하든 최종적으로 정답은 맞춘다. 그러나 실제 데이터는 모델러가 생각하였던 사상은 어디론가 사라지고 프로그래머에 의하여 왜곡되고 변형되어 간다. 그렇다고 이러한 현상이 프로그래머만의 잘못도 아니다. 데이터 모델을 자의적으로 해석하는 프로그래머에게도 문제는 있지만 애매모호한 데이터 모델 역시 문제이다. 각각의 엔티티가 표현하고자 하는 집합이 개발 단계부터 그저 정답 맞추기에만 급급하여 원래의 모습을 잃어버리거나, 본래 엔티티의 정의가 애매모호한 잡탕 집합으로 되어 있어서 개발 중에 자연적으로 변형되고 만다. 데이터 모델의 사상을 전달하고 관리하는 문서조차 변변히 없으니 앞으로 유지보수 시에는 또 다른 개발자에 의하여 얼마나 데이터가 손상되어갈 지 생각해보면 너무나 당연하지 않은가! 프로그램의 경우는 그나마 프로그램 소스 코드 내에 있는 코멘트라도 넣고 변경이 발생할 경우 수정한 날짜 및 변경자의 이름, 변경 내용 정도를 기록하는 최소한의 예의(?)라도 갖추지만, 데이터의 경우에는 테이블 레이아웃 변경 이외에는 문서로 어떠한 변경도 관리하지 않는다. 이것이 우리의 현실이며 만약 회사 내에서 누군가 회사가 가지고 있는 데이터를 정확히 꽤 뚫고 있다면 그 사람은 회사에서 매우 중요한 위치를 차지하게 될 것이다. 그럼 왜 이렇게 관리한거야?그렇다면 우리는 왜 이렇게 데이터를 관리하여 왔는가? 과거 수십 기가바이트가 대용량 데이터이던 시절에는 DBMS(Data Base Management System)의 역할이 그다지 크지 않았다. 단지 가용성 및 안정성을 높인 저장소의 역할에 지나지 않았으며 데이터의 접근 경로(DBMS를 통하여 데이터를 입출시키는 방법)를 프로그래머가 로직으로 직접 처리하여야 하므로, 이를 효율적이며 성능 좋게 로직으로 구사하는 프로그래머가 대접을 받던 시절이었다. 그러므로 데이터는 우리가 관리하고자 하는 효과적인 집합으로 구성하는 것보다는 프로그램 로직을 효과적으로 구사하는 데에 초점이 맞추어질 수밖에 없었다. 그러나 현재는 수 테라바이트의 데이터를 보유하는 시스템이 보편화되어있고 이를 관리하는 DBMS의 성능 및 기술(패러럴 처리 기능, 분석 기능, 분산처리 기능 등)이 비약적으로 발전하여 과거 복잡한 로직 및 SORT 유틸리티와 같은 툴을 사용하여도 할 수 없었던 대용량의 데이터 처리를 간단한 몇 줄의 SQL로 처리할 수 있게 되었다. 이제는 데이터 입출을 위한 프로그램 로직을 잘 만드는 사람이 중요한 것이 아니고 가능한 중복을 배제하면서도 효과적인 데이터 구조를 가지게 만드는, DBMS의 각종 기술을 잘 활용하여 간단한 SQL로도 엄청난 성능의 데이터 처리를 가능케 하는 사람이 중요하다. 과거와 같은 프로그램 로직을 위한 데이터 모델로는 막대한 데이터의 양을 감당할 수 없게 되었으며 급변하는 비즈니스 변화를 유연하게 대처할 데이터 모델 없이는 경쟁에서 살아남을 수 없게 되었다. 그러나 문제는 아직도 과거의 관행을 벗어나지 못한 데이터 모델이 많은 기업에서 사용되고 있고 만들어지고 있다는 것이다.무엇을 버려야 하는가?데이터 모델링의 잘못을 바로잡기 위해 가장 먼저 버려야 할 것은 데이터 모델링의 작성 수준에 관한 잘못된 인식이다. 데이터 모델링을 단지 테이블(table)과 컬럼(column)의 모습을 결정하는 과정 정도로 생각해서는 안 된다. 데이터 모델링은 아무 정보도 가지고 있지 않은 빈 백지 상태에서 시작해 현재(as-is) 업무를 파악하고 문제점을 도출하여 미래(to-be)의 최적의 설계를 이끌어내야 하는 과정으로 우리가 건축물을 설계할 때와 마찬가지로 인간만이 할 수 있는 분석력, 판단력, 종합력을 필요로 하는 고난위도의 작업이다.특히 데이터 모델링은 매우 구체적이고 상세한 수준으로 실시되어야 하며, 누구나 인정할 수 있는 객관적인 근거를 토대로 결정되고 그 결과가 입체적으로 표현되어야 한다. 상세한 수준으로 실시되지 않은 데이터 모델은 개발 단계에서 프로그래머의 작위적인 판단에 의해 변질되거나 훼손이 발생해 규칙은 깨어지고 복잡성은 갈수록 심해진다. 우리가 비록 다양한 토론과 많은 고민을 통해 결정한 사항들도 미래라는 이름의 변화하는 괴물은 계속해서 우리를 괴롭히기 때문에 머지않아 미래는 곧 현실이 되는 것이며, 미래를 미리 대비하지 않은 대가는 항상 우리의 발목을 잡게 된다. 더구나 데이터 모델링은 건물의 골조와 같은 것이기 때문에 상황에 따라서 쉽게 변경시키기가 매우 어렵다. 복덕방 평면도로 집을 만들어?ERD는 바로 설계도인 것이며 건물의 설계도처럼 상세하고 구체적으로 작성되어야 한다는 것을 의미한다. 우리가 알고 있는 도면에는 두 가지가 있다. 하나는 복덕방에 가면 볼 수 있는 ‘평면도’이며, 다른 한 가지는 건축현장에서 사용하는 ‘청사진’이다. 물론 평면도를 보아도 건축물이 어떻게 구성되었는지를 대략은 알 수가 있다. 안방, 건넛방, 마루, 식당 등이 모두 표시되어 있다. 그러나 이 도면은 건물을 짓는 사람들을 위한 도면이 아니라 그 건물을 사용할 사람을 위한 도면일 뿐이다. 만약 이 도면을 주고 아파트를 건축해 달라고 한다면 그는 정신병자 취급을 받을 것이다. 그러나 이런 상식을 초월한 일이 정보시스템 개발에서 자행되고 있다. 커다란 엔티티 박스에 그저 깨알같이 박혀 있는 속성뿐인 ERD나 복덕방의 평면도나 다를 것이 무엇인가! 거기 어디에 길이와 높이가 있고 재질이 나타나 있는가? 여기에 문이 있다는 표시만 있지 어떤 종류의, 어떤 높이의 문이 정확히 어디에 달려 있어야 하는 지는 전혀 나타나 있지 않다.우리가 작성한 ERD는 어떠한가? 가령 사원 엔티티가 있다고 가정했을 때 속성이 ‘사번, 성명, 주민번호,…’ 등으로 구성되어 있다는 것만 나타나 있지 구체적으로 정의되어 있는 것이 어디 한 가지라도 제대로 있는가? 다음의 그림을 통해 우리는 데이터 모델이 최소한 어느 수준까지는 작성되어져야 할 것인지를 서로 비교해 보기로 하자.

<그림 1> 사원 엔티티의 정의 비교
<그림 1>의 두 그림을 비교해 보자. 좌측의 그림은 엔티티가 사원을 관리한다는 것만 나타나 있을 뿐이다. 우측 그림은 우리가 관리하는 사원 엔티티가 ‘내근사원’, ‘설계사’, ‘대리점’으로 구성되어 있으며, 좌측 그림처럼 단순히 관리할 속성들이 나열만 되어 있는 것이 아니라 공통 속성들과 부분집합별 독립 속성이 구체적으로 나타나 있으며 다른 엔티티와 맺고 있는 관계 또한 공통 관계인지 특정 부분집합만이 갖는 개별 관계인지를 구체적으로 나타내고 있다. 또한 관계의 내용도 단지 선분만 그어져 있는 좌측과는 달리 관계의 구체적인 내용과 특기사항까지도 상세히 표현되어 있다. 이상에서 볼 수 있듯이 지금까지 우리가 작성한 데이터 모델은 평면도 수준을 넘지 못한다. 단지 컬럼 명과 데이터 타입(data type), 길이(length), 비고 등이 나타나 있는 ‘테이블 정의서’ 정도가 설계의 결과로 나타난 최종 산출물인 것이다.그럼 데이터 모델을 상세화할 수 있는 한 가지 방법 중에 하나인 ‘엔티티 정의서’의 상세화는 왜 필요한지 알아보자.
<그림 2> 엔티티 정의서의 예
엔티티 정의서의 상세화는 왜 필요한가<그림 2>는 엔티티 정의서의 일부분이다. 필자가 실전에서 접해 보았던 대부분의 시스템에서는 ERD가 평면도 수준으로 작성되어 있는 것은 고사하고 엔티티 정의서는 거의 엔티티들의 목록을 나열한 수준으로 작성되었고, 속성 정의서는 명칭, 길이, 타입 정도만 기술되어 있었다. 우리가 모델링 단계에서 구체적이고 상세한 정의를 하였다면 그 결과는 어딘가 기록으로 남아야 하며 특정 개인의 머리 속에 숨어 있어서는 안 된다. 어쩌면 상세한 기록을 남기지 않았다고 하기보다는 상세한 정의를 해본 적이 없었다는 것이 더 적절한 표현일지도 모른다. 혹자는 프로젝트 진행을 위해 지나치게 많은 산출물로 인해 정작 해야 할 일을 못한다고 푸념을 하고 있다. 단지 남에게 보고를 하기 위한 목적으로 불필요한 문서 작업을 과도하게 함으로써 실제 해야 할 일이 방해받고 있다면 그것은 분명히 잘못된 일이다. 그러나 생략을 하거나 간소화를 해도 될 일이 있고 절대로 그렇게 해서는 안 되는 것이 있다.엔티티 정의서를 구체적으로 작성하라는 것은 나중을 위해 문서를 남겨야 한다는 의도보다는 반드시 엔티티를 구체적으로 정의해야 한다는 필연성 때문이다. 이 작업을 하지 않거나 대충하겠다는 것은 전체적인 모델링을 대충하겠다는 의지(?)의 표현에 지나지 않는다. 최근에 수행되는 프로젝트 중에는 기존 시스템을 재구축하는 경우가 많이 있다. 이러한 시스템을 구축할 때 초기에 적용할 수 있는 가장 유용한 방법은 기존의 시스템을 역공학(reverse engineering)으로 분석해 보는 것이다. 기존 시스템을 모방하겠다는 것이 아니라 문제점과 부족한 점은 많이 있지만 그래도 업무 전반에 대한 가장 많은 내용을 담고 있으며 앞으로 우리가 개선해야 할 사항들을 구체적으로 찾아낼 수 있는 가장 빠른 방법이기 때문이다. 그러나 보유하고 있는 문서들은 언제부터인가 현재와 보조를 맞추지 못하여 현실과 따로 놀고 있으며, 작성된 내용도 충실하지 못하여 정작 우리가 알고자 하는 중요한 내용은 대부분 프로그램 소스 코드 속에 숨어 있는 실정이다. 좀더 구체적인 내용을 알기 위하여 현재 유지보수 담당자에게 질문을 해 보아도 속 시원한 답변을 듣기가 참으로 어렵다.현실을 감안한다면 프로그램 소스 코드 속의 각종 처리 과정을 일일이 문서화한다는 것은 결코 쉽지 않은 일이다. 그렇지만 그것보다 훨씬 단순하고 시스템의 기본이 되는 데이터 구조에 대한 정확한 문서화는 반드시 지켜져야 할 것이라 믿는다. 필자가 실전에 가서 컨설팅을 할 때 수많은 토론을 거쳐 엔티티의 정의를 명확히 하여 최종 결론을 내린 후 내일까지 누구나 구체적인 내용을 알 수 있는 정도로 엔티티 정의서를 작성해 오라고 숙제를 내면 거의 대부분의 사람들은 한두 줄 정도로 작성해 온다. 가령 고객의 정의를 사전적인 표현으로 ‘우리 회사의 고객을 정의한 엔티티’ 정도로 끝내 버린다. 이 정의만으로는 우리 고객이 법인, 단체도 포함되는지, 우리 상품에 가입하지 않아도 고객인지를 도저히 알 수가 없다. 적어도 엔티티 정의서라면 그 엔티티의 명확한 집합의 정의와 각 개체의 탄생 및 변경 경로, 실제 식별자와 의미상의 주어(나의 개체를 탄생시킨 부모가 되는 속성), 참조 테이블 및 참조 속성, 서브 타입의 정의 등은 최소한 표현되고 관리되어야 한다. 마찬가지로 속성 정의서 또한 단순한 컬럼의 타입이나 길이의 정의뿐만 아니라 각 속성의 정확한 의미와 특별한 값(코드화된 값의 의미)에 대한 상세한 설명, 반정규화에 의한 Derived 속성인지부터 식별자 및 FK(Foreign Key : 참조식별자)의 정의와 참조테이블에 대한 정의 등의 정보는 최소한 담아야 한다. 추가적으로 비즈니스 로직에 따른 각 경우의 수를 데이터화 하여 이를 정의된 엔티티들에 대입하여보는 Work-Though(또는 시뮬레이션 과정) 과정까지 수행한다면 금상첨화라 하겠다.데이터 모델의 객관화우리가 가장 쉽게 접하는 프로그램 개발은 제공되는 분명한 INPUT과 도출해야 할 OUTPUT이 확실히 나타난다. 작성 과정에서 자신이 실수한 것은 여러 방법으로 시험되고 증명된다. 처리 프로세스 하나하나가 모두 분명하고 자신이 무엇을 하고 있는지를 알고 있다. 논리적인 오류나 구문의 실수는 컴파일러가 검증해 주고 다양한 테스트를 통해 자신의 잘못은 명확하게 수정해 갈 수가 있다. 이에 반해 데이터 모델링은 그리 쉽게 자신의 실수를 인식할 수 없다. 온통 불확실한 것 투성이며 무엇부터 결정해 가야 할지 막연하기 그지없다. 더구나 자신의 판단으로 결정한 것들이 얼마나 완벽한 지도 확인하기 어렵다. 도대체 무엇부터 찾아내어 어디에 초점을 맞추어 결정해 가는 것이 올바른 것인지, 많은 고민을 통해 결정한 것들이 과연 어디가 잘못이 되었는지, 혹은 몇 점짜리가 되는 지 도무지 알 수가 없다. 어디가 어떻게 잘못이 되었는지를 구체적으로 안다면 어떻게 해서라도 보완하겠는데 나중에 프로그램 개발 단계나 테스트 단계, 더 심하면 유지보수 단계에 가서야 문제점이 나타나니 참으로 답답하기 그지없다. 데이터 모델링을 하는 설계자들이 하나 같이 고민하는 소리가 바로 이렇게 자신의 판단을 확신할 수 없다는 것과 옳은 지와 그른 지를 확인할 수 없다는 것이다.겁 없는 용기는 오늘도 싹튼다필자가 컨설팅을 수행하면서 어떤 결정을 보고 ‘어떤 근거로 판단했느냐?’라고 물으면 구체적인 답을 하는 사람을 보지 못했다. 대부분의 사람들이 ‘원래 그렇게 하는 거 아네요?’라고 막연한 반문을 하거나, 혹은 ‘이게 좋다고 하던데요?’, ‘우리는 지금까지 항상 이렇게 해 왔는데’라는 말들이 나온다. 분명한 판단의 근거를 가지고 복잡한 현실 요소들을 완벽하게 분석하여 전략적인 판단을 했더라도 전혀 예상하지 못한 변화로 문제를 일으킬 수 있는 것이 현실이다. 그럼에도 불구하고 무엇을 찔러보아야 할 지 조차 모르면서 겁 없는 결정을 계속해 갈 수 있다는 것은 참으로 대단한 용기(?)가 아닐 수 없다.모델링 또한 프로그래밍 못지 않게 객관화가 가능하다. 그렇지 않고 행해지는 수많은 결정들은 사상누각에 불과하다. 우리는 모든 부분에 있어서 이러한 객관적인 판단을 할 수 있는 근거를 발견하여야 하며 이러한 판단 근거를 찾는 훈련이 필요하다. 가령 예를 들면, ‘저기 길거리를 지나고 있는 사람들과 우리와는 관계가 있느냐’는 질문에 있다는 사람, 없다는 사람, 어떤 대답을 할 지 몰라 망설이는 사람, 이렇게 항상 세 종류의 사람이 있다. 또 다른 예를 더 들어 보자. ‘우리 할아버지와 나는 관계가 있느냐’라고 물어 보자. 할아버지하고 나하고 관계가 있다? 없다? 잘 모르겠다? 여러분은 어느 쪽이었는가? 어떻게 생각하면 매우 주관적일 수밖에 없는 이러한 상황을 누구도 아니라고 할 수 없는 객관적인 사실로 만들 수 있을 것인가? 이것이 우리가 훈련하여야 하는 중점 사항인 것이다.모델링은 모든 과정을 객관화시킬 수 있는 수단을 찾지 않으면 자신이 애써 결정한 것들이 물거품이 되고 만다. 그렇게 되지 않으려면 모든 부분에 있어서 누구도 꼼짝 못하게 하는 객관화를 시킬 수 있는 근거를 세우고 여기서 나오는 힘을 자신의 것으로 만드는 방법이 가장 중요하다. 시중에는 수많은 모델링 관련 서적과 강좌가 나와 있다. 이들의 대부분은 ERD를 작도하는 방법을 가르치고 있다. 다시 말해 그림을 그리는 방법을 교육시킨다는 것이며 이것은 분명히 잘못된 것이다. 모델링이라는 것은 인간의 사고를 통한 판단력으로 해 나가는 것이다. 그렇다면 판단하는 근거와 사고의 원리를 배우는 것이 무엇보다 중요하며, 그림을 그리는 방법만 익혀서는 아무 것도 제대로 할 수가 없는 것이다.우리가 속성 하나를 결정하는 데도 분명한 판단의 기준이 있다. 예를 들어 누구나 알 수 있는 ‘성명’을 ‘성’과 ‘명’이 각각 속성인지 결합한 것이 속성인 지를 물어보면 각자 대답이 다르다. 설계 시에 언제나 고민의 대상이 되는 ‘일자’를 년, 월, 일로 구분한 것이 속성인지, 결합한 것이 속성인지 판단해 보라. 결정했다면 그 판단의 근거가 무엇인가? 정확한 이유와 근거를 가지고 판단할 수 있는 힘이 있다면 자신의 결정이 하늘을 우러러 한 점 부끄럼이 없도록 할 수 있을 것이다. 이와 같이 완벽하게 처리하였다고 하더라도 언제라도 변할 수 있는 것이 바로 정보시스템의 세계이므로 우리가 해야 할 판단이 얼마나 어렵고 힘든 것이며, 얼마나 중요한 것인지를 명심해야 한다. 업무는 살아 있는 생명체와 같아서 수많은 변화를 필연적으로 수반한다. 그 변화에 적절한 대응을 하지 못하면 매일 저녁 밤을 새워서 고생을 하지만 앞으로 못 나가고, 뒤에 남아서 과거의 구멍난 곳을 때우는데 아까운 시간을 다 써버리는 불행한 일이 자꾸만 일어나게 된다. 그러므로 객관화를 통하여 데이터 모델을 명확히 한다면 이제 더 이상 자신의 결정에 불안해하지 않게 될 것이며, 발생할 수많은 시행착오가 줄어 들게 될 것이라 확신한다.데이터 모델링의 잘못된 유형여러 회사에서 리버스 모델링(reverse modeling)을 통하여 살펴본 잘못된 데이터 모델의 유형을 크게 세 가지로 나누고 있다. 첫 번째 유형은 ‘형제형’이라고 부르고, 두 번째 유형은 ‘족보형’, 마지막은 ‘네트워크형’이다. 누구나 동격인 ‘형제형’‘형제형’은 말 그대로 관계의 상하에 상관없이 누구나 동격(同格)이 되는 형제로 나타나는 형태를 말한다. 데이터 모델링이 한창 진행 중인 어떤 프로젝트에 가서 작성된 ERD를 보면 엔티티에 속성은 가득 차 있는데 어디에도 관계는 찾아 볼 수가 없는 경우가 많이 있다. ‘관계는 언제 맺어지느냐?’고 물어보면 조금만 더 있으면 맺어질 것이라면서 얼굴을 붉히곤 한다. 자식을 낳을 부모 엔티티는 아직 태어나지도 않았는데 자식 엔티티는 이미 태어나 속성까지 채워져 있다. 기업에서 발생할 행위 데이터들을 저장할 집합들은 지금까지 항상 가까이에서 사용해왔기 때문에 눈에 잘 보이지만, 이미 오래 전에 돌아가신 조상님(부모 엔티티)들은 눈에 보이지 않아 쉽게 찾아낼 수가 없기 때문이다. 그러다 보니 자식들부터 탄생하는 기현상이 발생한다. 자신이 어떻게 해서 태어났는지 출생의 비밀도 모르면서 속성들부터 마구 집어 넣는다. 더구나 그 속성이 정말 자기 것인지 아니면 조상 것인지, 그것도 아니면 주변에서 빌려 온 것인지도 확인하지 않은 채 우리가 관리해야 할 것처럼 보이니까 그냥 채워두는 것이다.
<그림 3> 형제형 데이터모델
이렇게 눈앞에 보이는 것들을 열심히 수집해서 채워 넣고 보니 관계는 없고 독립된 엔티티 박스에 깨알 같은 속성만 까맣게 채워져 있는 ERD가 만들어 진다. 그러다가 그림에 선(관계)을 안 그려 넣으면 그림이 이상하고 창피하니까 한참이 지난 다음에 결국 관계는 그려진다. 문제는 모델링에서는 1촌 관계만을 찾아 관계를 맺어 주어야 함에도 불구하고 어디나 있어야 할 ‘구분 코드’, 가령 ‘거래 구분’과 같은 자신의 출생과 별로 관련이 없는 엔티티와 관계를 맺어 준다. 그러다 보니 ‘거래 구분’과 이것과도 1:M, 저것과도 1:M이 된다. 마치 ‘할아버지’, ‘아버지’, ‘나’가 있는데 할아버지도 단군 할아버지의 자손이고, 아버지도 단군 할아버지의 자손이며, 나도 단군 할아버지의 자손이므로 결국 이들과 단군 할아버지는 모두 동일한 1:M 관계가 된다. 이 말은 곧 할아버지와 아버지, 나는 동일한 위치, 즉 ‘형제’가 된다는 있을 수 없는 일이 벌어지게 된다는 것을 의미한다. 물론 제일 위에 위치하고 있는 단군 할아버지가 보면 다 똑같은 자손임에는 틀림이 없다고 하더라도 이와 같이 이들 간의 관계가 형제라고 해야 한다는 것은 지극히 상식 밖의 일이 아닐 수 없다.이러한 일이 발생하는 이유는 모델링에서는 반드시 1촌 관계만을 표현한다는 원칙을 모르고 있었기 때문이다. 나와 아버지와의 1촌 관계를 정의하고, 아버지와 할아버지의 관계를 1촌으로 정의해 두면, 굳이 할아버지와 내가 2촌이라고 정의하지 않더라도 이들 간의 관계는 이미 2촌으로 정의되어 있는 것이다. 마찬가지로 삼촌과 할아버지는 1촌이므로 나와 굳이 3촌이라는 관계를 맺지 않더라도 저절로 삼촌이 되는 것이다. 물론 물리적 모델링 단계에 가서 다양한 물리적 요소들 때문에 접근경로를 단축하기 위해 1촌 이상의 관계들을 정의하는 경우도 있지만 이것은 아주 나중에 일어날 수 있는 것일 뿐이지 논리적 모델링에서는 그렇게 해서는 안 된다.부계 중심의 족보형두 번째 유형은 ‘족보형’이라고 표현을 하는 유형으로써 마치 대대로 물려 오는 족보처럼 부계(父系) 중심으로 작성된 데이터 모델을 말한다. 사실 우리가 편의상 어느 조상의 몇대 손이라고 말하지만 어떻게 우리 몸 속에는 부계쪽 피만 흐르고 있겠는가? 필자의 성이 ‘이’ 씨라고 해도 절대로 내 피에 이 씨의 피만 흐르는 것이 아니다. 족보상 이 씨의 혈통을 순수하게 받아온 것처럼 보인다. 그러나 우리 아버지의 성은 ‘이’ 씨겠지만 우리 어머니의 성은 ‘금’씨 였다. 우리 어머니의 어머니, 즉 외할머니의 성은 역시 ‘금’씨가 아니다. 그렇다면 온갖 혈통이 섞여 있는 것이지 어떻게 내 몸 속에 이씨 피만 흐를 수 있겠는가? 전통에 따라 아버지 입장에서만 족보를 쓰다 보니까 부계혈통만 이어받은 것처럼 보이지만 실제로는 나 자신이 태어나기 위해서는 반드시 아버지와 어머니가 있어야 하고 부계쪽 혈통만으로 탄생될 수는 없는 것이다.
<그림 4> 부계 중심의 족보형 데이터 모델
자신의 출생의 비밀을 밝히기 위해서는 반드시 양쪽 부모 모두가 밝혀져야 하는 것이지 어느 한쪽만으로는 불가능 하다. 이와 같이 모델링은 특히 논리적 모델링에서는 자신에게 피를 준 부모(우리는 이를 의미상의 주어라고 한다)를 명확히 규명해야 한다. 그렇게 해야 자신의 집합이 무엇인지 그 본질을 분명하게 밝혀 낼 수가 있는 것이다. 그러나 대부분의 모델링은 마치 족보처럼 아버지만 나타나 있고 나머지는 대부분 ‘일련 번호’로 표시되어 진다. 마치 낳아준 어머니가 누구였든 간에 어느 아버지의 몇 번째 아들로 표현되는 것과 마찬가지라 하겠다.가령 어떤 가족들의 자식들을 구체적으로 조사해 보니 사실은 서로 이복형제들이 섞여 있을 수도 있다. 또한 다른 부모가 낳은 자식을 양자로 들여 왔을 수도 있다. 데이터 모델은 필요에 따라 상위 부모 엔티티의 정보를 참조할 필요가 있으므로 반드시 이러한 구체적인 관계가 밝혀져야 하고 그것이 데이터 모델에 구체적으로 나타나야 한다. 대부분의 경우 이러한 관계는 숨어 있어서 잘 보이지 않으며, 대부분의 경우 애플리케이션 로직(logic) 속에 숨어 있는 경우가 많이 있다.길게 늘어져 있는 네트워크형세 번째 유형은 ‘네트워크형’이라고 표현할 수 있는데, 이러한 유형은 마치 네트워크 도면에서 나타나는 것처럼 길게 선이 하나 늘어져 있고, 중간 중간에 하나씩 라인을 빼서 단말기를 붙이는 것과 유사한 형태를 말한다. 중요한 역할을 하는 엔티티가 군데군데 위치해 있고 거기에서 길게 선분을 그은 다음 중간에 선을 하나씩 끄집어 내어 엔티티를 달고 있는 모습은 네트워크 도면과 너무도 흡사하다. 실제로 어떤 시스템에서라도 이런 유형의 데이터 모델은 절대로 나타날 수가 없다. 아무리 많은 역할을 하는 중요한 엔티티가 있다고 하더라도 옛날 왕(王)이 그랬듯이 수십 명의 1촌 자식들을 거느릴 수는 없을 것이다. 만약 실제로 이러한 모습이 나타난다면 그것은 필시 하나의 엔티티를 물리적으로 수직분할하여 여러 개로 잘라놓은 것이 틀림없을 것이다. 실전에서 나타나는 데이터 모델에는 1:1이 많이 발생하고 있는데, 대부분의 경우 물리적 설계 단계에서 수행속도를 두려워하여 지나치게 수직 분할을 했거나, 프로세스의 진행에 따라 단계마다 엔티티를 만든 경우로 보아야 한다.데이터 모델에는 순서와 시간, 흐름의 개념이 들어가지 않는다. 이러한 개념을 넣어서 마치 DFD(Data Flow Diagram)처럼 업무의 흐름에 따라 엔티티가 발생하는 경우를 많이 발견하게 되는데 혹자는 이를 가리켜 EFD(Entity Flow Diagram)라는 신조어를 사용하여 잘못을 호되게 질책하기도 한다.이상과 같은 잘못된 유형의 데이터 모델이 나타나는 원인은 데이터 모델링 접근 방식의 근본적인 잘못에서 비롯되었다고 할 수 있다. 데이터 모델링은 현실에 흩어져 있는 수많은 요소들을 마치 방정식을 풀듯이 하나하나 단계적으로 구체적이고 명확하게 정의해 가는 것이다. 방정식이 그러하듯이 미지수가 있는 채로는 방적식의 해를 구할 수 없다. 우리가 학교 다닐 때 풀어보았던 방적식은 먼저 풀어야 할 미지수를 찾아 그것을 상수화(常數化) 시키고, 그 결과를 다음에 풀 미지수에 대입하는 방식으로 미지수를 줄여나가야 한다. 이와 같이 모델링에서도 현실에 있는 무수한 불확실성을 해결하기 위해 먼저 해결해야 할 것과 그 결과를 이용하여 해결해야 할 필연적인 종속성(dependency)이 존재한다. 다시 말해 먼저 정의되어야 할 것과 그것이 정의되어야 이것이 정의될 수 있다는 식의 결정 순서가 분명히 있다는 것이다. 이것을 무시하고 눈에 보인다고 무턱대고 가까이 있는 것부터 정의해 가면 반드시 모순이 따르게 되고 결국에 가서는 서로 엉켜 버린다는 것을 알아야 한다.내 자신이 누구인 지를 정확히 알지 못하는데 내 자식이 누구인 지를 어떻게 알 수 있겠는가? 아직도 우리는 설계는 대충해두고 특이한 상황이 발생하면 프로그램에서 어떻게 처리하면 될 것이라는 생각을 하고 있고, 또 지금까지 그렇게 해왔는지도 모른다. 프로그램을 하나하나 작성해 나갈 때는 상세한 내용이 일일이 드러나지만 설계 단계에서 모든 내용을 상세화하기란 정말 어렵고 짜증나는 일일 것이다. 이런 이유로 설계 단계에서는 대충 윤곽만 잡아 두고 프로그램 작성 단계에서 고쳐 가는 것이 오히려 마음이 편했는지도 모른다. 그러나 이제는 그렇게 해서는 안 된다. 초가삼간을 지을 때는 간략한 도면만 있어도 가능할 지 모르겠지만 대형 건물을 지으면서 복덕방에서 볼 수 있는 평면도 수준의 도면으로 접근해서는 안 된다.비효율적인 데이터 모델의 사례여러 회사를 컨설팅하면서 보았던 문제의 데이터 모델 중에서 독자들이 공감할 만한 실제 사례 몇 가지를 통하여 데이터 모델이 얼마나 큰 영향을 미치는 지 알아보자.
<그림 6> 컨텐츠를 제공하는 인터넷 회사의 주요 ERD 예
식별자를 잘못 선택해 벌어진 일첫 번째 사례는 식별자를 잘못 선택하여 벌어진 일이다. 원래의 것을 각색하기는 하였으나 원래의 문제점을 독자에게 전달하는 데는 문제가 되지 않으리라 생각된다. 어느 인터넷을 통하여 각종 컨텐츠를 제공하는 회사에서 고객과 맺은 ‘서비스 계약’이라는 집합을 정의하였다. 이 집합은 회사로부터 ‘회원’이 서비스를 받는 기본 단위가 되고 서비스 계약 또는 이들의 묶음 단위로 청구 및 입금을 할 수 있도록 ‘청구 계약’을 가지며 하나의 회원은 여러 개의 서비스 계약을 가질 수 있으나 동일 회원의 복수 개의 서비스 계약은 별개의 청구 계약에 속해야 한다는 비즈니스 규칙을 정의하였다. 또한 서비스 계약은 이 회사가 제공하는 컨텐츠를 구독하는 여러 옵션에 따른 ‘상품’들을 선택할 수 있는데 서비스 계약별로 선택된 상품을 관리하는 집합을 ‘서비스 상품’이라고 하며 과금을 위해서는 ‘청구 계정’ 단위로 관리를 하여야 하므로 계약 서비스가 갖는 청구 계정을 ‘서비스 계정’이라고 하기로 하였다. 이와 같은 비즈니스 규칙을 ERD로 표현하면 <그림 6>과 같이 표현될 수 있으며 비즈니스 규칙에 따라 집합의 정의가 잘 내려진 데이터 모델인 것으로 보인다.그러나 문제의 발단은 서비스 계약의 식별자를 어떻게 가지고 가느냐 하는 결정이 문제였다. 데이터 모델러는 회원들의 전화번호가 서비스 계약을 찾는 주요 키라고 생각하고 서비스 계약의 식별자를 [청구계약번호+회원전화번호]로 만들었다. 이렇게 만들어진 모델에서 이 회사가 가지고 있는 회원의 숫자가 1000만 명이고 이들이 가지는 서비스 계약이 3000만 건이며 각 서비스 계약은 평균 3개의 서비스 상품과 평균 5개의 서비스 계정을 갖는다고 가정하여 보자. 여러분도 쉽게 예상해 볼 수 있듯이 회원의 전화번호는 수시로 바뀔 수 있다. 이와 같은 모델에서 회원의 전화번호가 바뀌면 서비스 계약의 새로운 개체(신규 레코드)를 생성시키거나 식별자를 변경시켜야 한다. 그나마 식별자를 변경하는 것으로 하였다면 레코드 수는 늘어나지 않겠지만 문제는 과거에 만들어진 서비스 계약을 참조하고 있는 각종 정보(예를 들어 서비스 상품, 서비스 계정, 청구, 수납, 미수, 과금 내역 등)에 들어 있는 참조 키들도 변경시켜야 하는 문제에 봉착할 수밖에 없다. 서비스 계약이 3000만 건이면 앞에서 예를 들었던 각종 정보는 과거 1년 치만 하더라도 얼마만한 양이 되겠는가? 이것도 문제라고 생각되니 결국 서비스 계약에 회원전화번호가 바뀌면 신규로 개체를 생성하는 것으로 하였다. 예상대로 서비스 계약의 신규 건은 실제로 서비스 상품이나 서비스 계정에는 전혀 변화가 없다고 하더라도 부모가 새로 태어났으므로 신규로 전에 있던 내용을 그대로 복제하여 단지 참조 키만 달라진 채로 신규 생성할 수밖에 없었다. 그러므로 기하급수적인 불필요한 데이터를 양산하게 되었으며 서비스 계약의 경우에도 실제 계약 한 건이 회원전화번호 변경으로 여러 개의 복수 건이 되었으므로 ‘우리 회사에는 몇 개의 서비스 계약이 있는가?’라도 누가 묻는다면 정답을 주기가 만만치 않을 것이다. 그럼 과거 건과 연결고리를 맺어놓으면 되지 않느냐고 반문할 수도 있으나 이는 각종 프로그램의 복잡성을 가중시킬 것이 자명한 일이다.언뜻 보기에 조금 과장하기는 하였지만 이런 실수가 실제 벌어질 수 있는가 하는 의문을 갖을 수 있으나 이와 유사한 일이 실제 일어나고 있고 한번 개발된 시스템을 전면 수정하기 매우 어렵다는 점에서 모델러의 한 순간의 실수가 영원히 벗기 어려운 짐으로 작용할 수 있다는 것을 교훈으로 얻을 수 있다.정규화를 제대로 알고 있나요?두 번째 사례는 우리가 데이터 모델링 시에 알면서도 잘 적용하지 않고 있는 정규화를 지키지 않은 경우다. 한 회사에서 공산품 한 개를 조립하고 출하하기까지는 많은 공정이 따르는데 이를 다음과 같이 하나의 엔티티로 모델링 하였다고 가정하자.
<그림 7> 제품의 진행 내역 관리의 예
<그림 7>의 왼쪽과 같이 제품의 진행내역을 제품 개체를 관리하는 엔티티에 관리한다면 각종 일자에 들어 있는 속성의 값들은 반복될 것이고 이는 정규화의 위반인 셈이다. 왼쪽과 같은 모델에서 ‘특정 생산라인을 오늘 거친 제품들을 모두 찾아라’라는 질문이 던져진다면 어떻게 SQL을 구사할 것인가? 십중팔구 이런 식으로 구사할 것이다.SELECT …FROM 제품별진행내역WHERE ( IN라인일시 LIKE :V_DATE