DATOR


데이터 모델링 왜 잘해야 하나요?. . . . (주)엔코아 이정수 이사 커버 스토리


coverstory201309.jpg

 

데이터 모델링 컨설턴트로서 프로젝트 관계자들과 토론을 하다 보면, 서로가 도대체 왜 저렇게 생각할까 하는 의문이 들 정도로 치열하게 의견을 나눌 때가 있다. 감정을 배제하고 끈질기게 토론을 이어가다 보면 데이터 모델링에 대한 생각이 나와 달라서 그렇구나 하고 깨닫게 되는 경우가 많다. 대체로 경력자일수록 데이터 모델에 대한 기대가 적은 편인데, 그것은 아마도 잘못된 모델로 인해 문제가 될 만한 사항을 알게 모르게 자신의 능력으로 커버하곤 했었기 때문이라 생각된다. 하지만 데이터 모델의 문제를 개발자의 능력으로 커버할 수 있다고 해서 데이터 모델링을 아무렇게나 해도 된다고 결론을 내는 것은 매우 안타까운 일이다. 왜냐하면 데이터 모델링이 잘 수행되면 문제가 발생하지 않게 하거나 좀 더 적은 자원으로 문제를 해결할 수 있기 때문이다.

 

가끔은 데이터 모델링을 왜 잘해야 하는지에 대해 도전적인 질문도 받게 되는데, 조금은 안타까운 마음으로 데이터 모델링 시의 고려 사항을 설명하면서 생각의 차이를 없애려고 노력하게 된다. 고려 사항을 위주로 설명하는 이유는 이 항목들이 곧 데이터 모델링의 효과가 되기 때문이다.

 

데이터 모델링 시의 고려 사항 중 가장 놓치기 쉬우면서도 이슈가 발생하면 그것을 바로 잡는데 시간과 노력이 가장 많이 투입되어야 하는 항목이 있는데 바로 유연성이다. 유지보수 단계에서 요청된 요구사항을 컬럼이나 코드 값 1개 추가로 수용할 수 있다면 애플리케이션의 수정 폭도 상당히 작겠지만, ‘신규 테이블 10여 개 추가테이블 통합또는 테이블 분리등이 일어나야 한다면 데이터 모델링뿐만 아니라 애플리케이션의 생성과 수정 작업에도 상당한 시간과 자원을 투입해야만 한다.

 

따라서 가능한 작은 자원의 투입으로 시스템의 구축 이후의 요구 사항을 수용할 수 있도록 하는 것은 매우 중요한 고려 사항 중 하나라 할 수 있다. 유연성과 관련하여 실전에서 많이 발생하는 문제는 유연성이 앞으로 설명할 성능이나 SQL 복잡도와 대치되는 관계에 놓이기 쉽다는 점이다. 많은 프로젝트에서 원활한 수행을 위하여 성능이나 SQL 복잡도를 강조하느라 유연성 측면의 희생이 발생하게 되는데, 유지 보수 단계에서 이를 바로잡기 위해서는 다시 한번 대대적인 프로젝트를 수행해야 할 수도 있으므로 IT 관리자라면 상당히 신경 써야 하는 부분이다.

 

유연성 측면에서 IT 관리자가 신경 써야 하는 점을 추가한다면, 데이터 모델의 유연성에 문제가 있더라도 실제로는 데이터 모델을 유연성 측면에서 평가하기는 매우 어렵다는 것이다. A기업에서는 하루 만에 반영한 요구 사항을 B기업에서는 수십 개의 테이블을 추가하고 애플리케이션을 개발해야 해서 수 개월이 걸렸다고 하더라도 A기업의 유연한 시스템을 설계하고 개발한 사람보다는 수 개월간 힘든 프로젝트를 잘 해낸 B기업의 담당자가 칭찬받는 것이 현실이다. 매우 유사한 상황이 성능과 관련해서도 나타나는데, C기업에서는 처음부터 수행 시간이 1분인 특정 레포트 출력 작업이 D기업에서는 처음엔 3시간이었는데, 수 주 간의 노력으로 수행 시간을 1시간으로 줄였다면, C기업의 모델러나 레포트 작성자 보다는 D기업의 담당자가 인정받는 상황도 발생하고 있으니 매우 안타까운 아이러니이다.

 

데이터 모델링의 고려 사항 중 가장 먼저 떠오르는 항목은 아무래도 성능일 것이다. 그런데 성능과 관련해서 가장 쉽게 간과하는 사실 중의 하나가 성능 문제는 생각보다는 쉽게 해결할 수 있다는 점이다. 많은 개발자들이 SQL을 조금 수정하거나 INDEX를 추가했더니 수행 속도가 엄청나게 향상됨을 경험했을 것이다. 물론, 모델의 변경을 제외한 방법으로는 성능 이슈를 해결할 수 없는 상황도 발생할 수 있지만, 대부분은 모델 변경 없이 튜닝만으로 상당한 효과를 나타낼 수 있다. 따라서 데이터 모델을 성능 측면에서 바라보는 시각은 성능 향상을 위해 얼마나 많은 자원을 추가로 투입해야 하는가가 되어야 한다. , 상대적으로 작성과 수정이 쉬운 SQL 만으로, 상대적으로 적은 인덱스 생성으로, 상대적으로 적은 H/W, N/W 등의 자원 투입으로도 괜찮은 속도가 보장되도록 데이터 모델을 설계해야 한다.

 

또 하나의 데이터 모델링 고려 사항으로는 SQL 복잡도를 고려해야 한다는 것으로, 데이터 모델로 인해 SQL을 더 복잡하게 작성하도록 만들지는 말아야 한다는 점이다. 특정 테이블을 검색할 때 항상 다른 테이블과의 조인이 있어야만 하거나, 두 개 이상의 상위 테이블과 OUTER 조인이 자주 발생하거나, A 테이블과 조인하기 위해서 항상 B 테이블과의 조인을 먼저 해야 하거나, 검색 조건이나 조인 조건이 항상 복잡해져야 한다면 해당 데이터 모델의 변경을 검토해 보아야 한다. 더불어, SQL 복잡도를 검토할 때에는 해당 테이블을 얼마나 많은 사람들이 검색하게 될 것인지도 검토해 보아야 한다. 어느 정도 복잡도가 증가하더라도 관련된 SQL 개수가 매우 적다면 다른 고려 사항을 더 중요하게 판단해야 할 것이다. 반대로 많은 사람들이 자주 사용하게 될 테이블이라면 적은 복잡도의 증가 만으로도 시스템 전체적으로는 큰 악영향을 미칠 수도 있다.

 

성능과 함께 데이터 모델링의 고려사항 중 하나로 쉽게 생각할 수 있는 것이 데이터의 품질이다. 아마도 모델링 원칙 등을 통하여 중복 데이터의 관리를 지양해야 한다는 미션이 많이 공유되고 있기 때문이겠지만, 중복 데이터 설계 이외에도 도메인 표준화, 유사컬럼 통합, 코드 표준화, 컬럼 전용 금지, 데이터 모델의 가독성 등 직간접적으로 데이터 품질을 좌우하는 데이터 모델의 요소가 많으므로 항상 신경 써야 하는 고려 사항이다. 그러나 데이터 품질 면에서 데이터 모델에 내포된 문제점도 그리 어렵지 않은 해결 방안이 존재할 가능성이 크므로 데이터 품질이 떨어질 수 밖에 없는 모델이라고 해서 무조건 배척하지는 말아야 한다. 예를 들어, 성능이나 유연성을 위하여 동일한 컬럼을 2개의 테이블에 저장하거나, 동일한 의미의 컬럼이지만 실제로는 다른 도메인으로 설계되더라도, 모델에 충분히 그 사유와 주의할 점을 표현하고 애플리케이션 작성 시에 해당 규칙을 반영하거나, 일 또는 주간 배치 작업으로 잘못된 데이터 값을 추출하여 수정하게 한다면 상당 부분 문제를 해결할 수 있다.

 

마지막 데이터 모델링의 고려 사항으로는 관리 용이성으로 데이터 모델로 인한 부가 작업량을 가능한 줄여야 한다는 의미이다. 예를 들어, 변경될 수 있는 주민번호 컬럼을 고객 테이블의 PK로 삼고 하위 테이블에 상속한 경우, 주민번호를 UPDATE한다면 하위 테이블의 모든 주민번호 컬럼도 UPDATE해야만 데이터 일관성을 보장할 수 있다. 하위 테이블의 개수가 적으면 그나마 다행이겠지만, 실제로는 수십 개 이상의 테이블에 주민번호가 존재할 것이므로 그 만큼의 UPDATE 문장의 작성이 필요하며, 대용량으로 예상되는 트랜잭션 레벨의 테이블은 경우에 따라 수십만 건에 이상의 로우를 UPDATE해야 하는 경우도 발생할 수 있다. , 속성 메타 등의 구조에서는 로우 건수가 너무 빨리 증가하여 주 단위, 월 단위의 백업 작업과 파티션 관리 작업이 요구될 수도 있다. 그 외에 성능을 향상시키기 위해 동일한 데이터를 이곳 저곳에 중복해서 만들거나, 발생할 가능성이 거의 없는 미래의 상황까지 대비해서 관리하기 힘든 데이터 타입을 사용하는 등 관리 용이성을 고려하지 않아 유지 보수 단계에서 크고 작은 이슈가 만들어질 수 있다.

 

기타 잘 작성된 데이터 모델은 관련자 간의 커뮤니케이션 시의 비주얼한 기본 자료로 활용될 수 있으며, 데이터 모델링을 제대로 수행한다면 그 자체가 훌륭한 분석 방법론인 점은 데이터 모델링 시의 고려 사항은 아니지만, 데이터 모델링의 좋은 효과가 될 것이다.

 

데이터 모델러는 위의 고려 사항을 염두에 두고 모델링을 진행해야 하는데, 보기에는 간단한 항목들이지만, 실제 업무에 적용하기 위해서는 좀 더 깊은 지식과 경험이 요구된다. 다음은 모델러가 얼마나 많은 생각을 하여야 하는가에 대한 간단한 예이다.

 

진료기록 테이블(진료ID, 변경순번, 환자번호, 기록일시, 진단코드, …) : 진료ID와 변경순번이 PK

 

위는 병원시스템에서 의사의 진료기록 테이블 구조로 진료ID와 변경순번이 PK이며, 환자번호, 기록일시, 진단코드 등이 구성 컬럼이다. 변경순번이 PK에 포함되어 있으므로 의사가 진료한 기록을 수정하는 경우 순번을 증가시킨 새로운 레코드를 생성할 것임을 알 수 있다.

 

동일한 진료ID 중 최종 유효한 기록은 변경순번이 최대인 기록일 것이다. 따라서, 매번 유효한 기록을 읽으려면 MAX(변경순번)을 읽어서 해당 변경순번을 알아낸 후 다시 진료기록 테이블과 조인해야 한다. 하나의 레코드만 읽을 때는 그런대로 어렵지 않게 SQL을 작성할 수 있지만, 여러 번 진료한 환자의 전체 기록을 조회하는 SQL을 성능까지 고려해서 작성하기가 좀 어려울 것이다. 튜닝을 해 본 사람이라면 INDEX DESC 힌트와 ROWNUM 조건을 사용하면 어떠냐고 제안할 수도 있는데, 이 방법을 사용하더라도 SQL 작성이 MAX(변경순번)보다는 좀 쉬워지긴 하지만 어느 정도의 복잡함은 아직 남아있으며, 자칫하면 결과값이 달라질 수도 있으므로 권장하지 않는 방법이다. 결과적으로, SQL 복잡성과 성능 측면에서 별로 좋지 않은 모델인 것이다. 그런데 조금만 생각해 보아도 진료기록은 대부분 최종 기록만 조회하지 과거의 기록은 그야말로 기록일 뿐 다른 애플리케이션에서 검색할 가능성은 아주 낮으므로 기본적인 해결 방향을 쉽게 도출 할 수 있다.

 

해결 방향은 당연히 최종 진료기록을 쉽게 읽어올 수 있도록 구성하는 것인데, 그 방법은 크게는 최종 기록임을 알 수 있는 컬럼을 추가하는 방법과 최종 기록만 유지하고 나머지는 이력 테이블에서 관리하는 방법 이 2가지이다. 그런데, 컬럼을 추가하는 방법에도 최종기록여부 컬럼을 추가하는 방법과 유효종료일시 컬럼을 추가하는 방법 2가지로 나눌 수 있으며, 이력 테이블을 별도로 관리하는 방법에도 선분이력으로 가져가느냐 점이력으로 하느냐를 선택해야 하고, 최종 진료기록을 이력 테이블에도 저장할 것인가도 결정해야 하며, 모든 컬럼을 이력으로 저장할 것인가도 결정해야 한다.

 

데이터 모델링 시에 위와 같은 사고를 할 수 있는 사람이 모델러가 되어야 함은 당연할 것이다. 위와 같은 간단한 모델링이라도 자신 있게 설계하려면 튜닝 및 SQL 작성 능력 외에도 최종 진료기록만 사용될 가능성이 높을 것이다라든가, ‘진료기록의 변경 전 기록을 검색하는 경우는 거의 없으므로 이력테이블에 최종 진료기록을 포함시킬 필요는 없어 보인다와 같은 판단을 하기 위해서는 업무 및 애플리케이션 작성 경험이 필요하다.

 

실전에서는 데이터 모델링의 고려 사항 중 유연성과 성능, 유연성과 SQL복잡도, 유연성과 데이터 품질, 데이터 품질과 성능, 데이터 품질과 SQL복잡도 등이 양립하기 어려운 경우가 많이 발생하는 조합이며, 모든 항목을 만족시키는 데이터 구조를 도출하지 못하는 경우도 종종 발생한다. 따라서 모델러들은 데이터 모델링의 고려 사항을 모두 달성하는 모델링이 아니라, 문제가 되는 상황을 현실적으로 해결할 수 있거나, 다른 항목을 중요하게 고려하느라 특정 항목은 덜 고려되었지만 관계자가 수긍할 수 있는 모델링을 수행해야 한다.

 

다음은 실제로 프로젝트를 진행하면서 매우 자주 부딪히는 테이블의 통합/분리의 몇 가지 사례이다.

 

병원의 초기간호기록과 퇴원간호기록, 쇼핑몰의 회원주문내역과 비회원주문내역, 은행의 카드발급내역과 통장발급내역, 대학의 학부학적과 대학원학적, 기업의 직원과 외부전문가

 

위의 통합/분리 사례 중 하나라도 보자마자 판단할 수 있는 것이 있다면 과연 그 판단이 종합적인 판단인지를 생각할 필요가 있다. , ‘두 테이블은 동일한 것’, ‘지금까지 그렇게 해왔다또는 누가 보더라도 통합해야 한다라는 생각 만으로 결론을 내지는 말아야 한다. 위에 든 모든 예는 통합과 분리된 구조 모두를 실전에서 목격했던 사례로, 최소한 지금까지 그렇게 해왔다누가 보더라도 통합해야 한다는 설명에는 반대의 사례가 되는 셈이다.

 

모델링의 고려 사항에 맞추어 테이블의 통합/분리를 고민해 보면, 성능 측면에서는 분리를 지지하는 경우가 많은데, 일반적으로 통합으로 인한 성능 저하의 가능성 때문이라고 설명한다. 실제로는 통합으로 인해 데이터가 많아지므로 당연히 FULL SCAN의 성능은 떨어지지만, 성능을 걱정할 만한 대부분의 대용량 테이블에 대한 검색에서 FULL SCAN으로 자료를 검색할 가능성은 거의 없으므로 올바른 설명은 아니다. , 통합으로 인해 조인의 횟수가 늘어날 수 있다는 우려도 있지만, 실제로 조인의 횟수를 결정하는 것은 드라이빙 테이블의 검색 조건에 의해 결정되는 것이므로 적절한 검색 조건을 줄 수 있다면 통합으로 인한 조인 성능 저하는 일어나지 않는다. 오히려 분리하게 되면 부분범위처리가 어려워져 성능이 나빠지거나 SQL 복잡도가 증가하는 경우도 종종 발생한다. 모델의 통합/분리 여부를 성능 측면으로 보다 상세히 논하려면 매우 많은 시간과 지면이 필요하므로 결론만 내려보면 통합하면 성능이 떨어질 가능성이 크다정도의 논리만으로 분리를 결정하지는 말아야 하며, ‘성능 문제는 여러 방법으로 해결 가능하므로 다른 항목을 검토하여 통합/분리를 결정한 후 그 결정에 따라 예상되는 성능상의 문제에 대한 해결 방안을 도출한다정도로 정리할 수 있다..

 

한편, 데이터 양의 증가와는 상관없이 데이터 형식(데이터 타입과 길이)이 통합으로 인해 표준과 달라지는 상황이 발생할 수 있다.

 

예를 들어 사원번호는 NUMBER(12), 외부전문가번호는 VARCHAR(10)이 표준인 상황에서 사원과 외부전문가 테이블을 통합한다면 신규 컬럼은 VARCHAR(12)로 지정하게 될 것이다. 이렇게 되면 조인 조건에 타입이 다른 상황에 대한 처리를 해 주거나, 함수 기반 인덱스를 만들어야 하는 등 성능과 SQL 복잡도 측면에서 문제가 발생할 수 있다. 따라서 통합으로 인해 위와 같은 이슈가 예상되면 해당 테이블이 다른 테이블과의 조인이 거의 없음을 확인하거나, 외부전문가번호의 표준을 NUMBER 타입으로 변경하는 등의 대안을 제시하는 것이 바람직한 모델러의 자세일 것이다.

 

카드발급내역과 통장발급내역 테이블의 통합 여부를 SQL복잡성 측면에서 검토해 보면 통합한 경우가 아무래도 SQL의 복잡도가 증가할 것이라고 예측하기 쉬운데, 통합으로 인해 복잡해 지는 정도는 SQL의 조건절에 발급매체 = 카드정도만 추가되는 것이므로 그리 심각하게 느낄 필요는 없다. 오히려 테이블은 분리하였지만 분리된 여러 테이블을 하나의 SQL에서 자주 다루어야 해서, SELECT 문장을 UNION 으로 계속 연결해야 하거나, 상위 엔터티와의 OUTER 조인이 연속해서 사용되는 상황이 나타나기도 한다. 결과적으로 테이블의 분리로 인한 SQL의 복잡도 증가는 통합으로 인한 증가보다 더 심각해 수 있으므로 분리된 테이블들을 동시에 검색하거나 변경해야 하는 경우가 별로 없음을 확인해야 한다.

 

한편, 화면설계를 기준으로 화면이 카드발급 화면과 통장발급 화면으로 분리되어 있다면 카드발급 테이블과 통장발급 테이블로 분리하고, 반대로 하나의 화면에서 발급이 처리되도록 설계되어 있다면 매체발급 테이블 하나로 통합하자는 의견이 좋아 보일 수 있다. 그런데, 화면은 비즈니스의 변화에 따라서 쉽게 추가되거나 변경될 수 있으나 시스템 오픈 이후의 테이블의 통합이나 분리는 훨씬 큰 작업임을 감안한다면, 화면이나 어플리케이션과의 1:1 조합을 맞추기 위해 테이블의 통합과 분리를 결정하는 것은 유연성 면에서 잘못된 방법이다. 유연성 면에서는 향후 새로운 발급매체의 추가 가능성을 파악하여 어느 정도의 가능성이 있다면 발급매체내역이라는 통합된 테이블을 설계하는 것이 좋다. 여기서 적극적인 모델러라면 조금 더 나아가 화면도 매체발급화면으로 통합하는 것을 화면 기획자에게 제안할 수도 있을 것이다. 아마도 이런 화면을 만들게 된다면, 향후 다른 종류의 매체가 추가되더라도 애플리케이션의 변경 가능성을 최소화시킬 수 있기 때문이다.

 

테이블의 통합 시에는 아무래도 모델의 명확성이 떨어지는 현상이 나타날 수 있다. 앞에서 예로든 사원 테이블과 외부전문가 테이블을 통합하게 되면, 사원번호와 외부전문가번호 대신 관계자번호와 같이 다른 명칭을 부여하거나, 사원번호 컬럼을 사용하기는 하지만 실제로는 외부전문가번호도 포함될 수 있음을 다른 방식으로 설명하여야 한다. 또한, 데이터 형식이 달라지는 경우도 발생할 수 있으므로, 이렇게 된다면 악영향까지는 아니더라도 데이터 품질을 유지하는데 조금 더 신경을 써야 한다. 반대로 테이블을 분리하게 되면 동일한 의미의 속성이 자칫 다른 속성명으로 저장되고, 그 결과 데이터 타입까지 달라질 수도 있으므로 분리 결정 시에는 보다 주의해야 있다. 그러나 어떤 경우든 모델링 시에 좀 더 표준화를 철저히 한다든지, 어플리케이션 작성 시에 데이터 품질에 조금 더 신경을 쓴다면 큰 문제의 발생 가능성은 상당히 낮출 수 있으므로 데이터 품질을 주요 고려사항으로 간주하기 보다는 통합이나 분리와 상관없이 데이터 모델링과 애플리케이션 작성 시에 표준을 잘 지켜나가는 것이 중요하다.

 

지금까지 데이터 모델링 시의 고려사항과 사례를 나열해 보았는데, 사실 위 항목들을 모두 고민하면서 데이터 모델링을 진행하기가 쉽지 않은 만큼 실전에서 다른 사람이 작성한 데이터 모델의 좋고 나쁨을 판단하기도 매우 어렵다. 그렇기 때문에 작성한 모델에 대해 몇 가지의 그럴 듯한 이유를 붙이고, 이슈가 될 만한 것은 목소리 큰 사람의 의견을 반영하면 그런대로 지적 받지 않는 모델러는 될 수 있다.

 

그러나 자신이 설계한 모델에 보다 자신 있는 모델러가 되려면 위의 고려 사항에 더하여 자신만의 시각으로 모델링 대상 업무와 상황을 판단하여 가장 적합한 결론을 내려야 한다. 모든 항목을 만족시키는 모델을 만들 수는 없는 상황에서의 최선의 결정이란 가장 중요한 고려 사항들은 만족하면서도 나머지 고려 사항들에서는 심각한 문제가 발생하지 않도록 데이터 모델을 설계하는 것이다. 나아가 문제가 될 만한 사항들을 설명하고 어떻게 하면 심각한 문제를 예방할 수 있는지를 밝혀 두는 것도 모델러가 수행함 직한 일이 될 것이다.

 

 

Tag :

Leave Comments