데이터 인사이트

데이터 전문가 칼럼
데이터 전문가가 전하는 데이터 노하우

노찬형의 제로에서 시작하는 데이터 모델링 시즌II (8회) : 데이터 모델링에서 속성명 도출의 원리

작성자
관리자
작성일
2020-08-28 18:22
조회
57

노찬형의 제로에서 시작하는 데이터 모델링 시즌II (8회)

 

데이터 모델링에서 속성명 도출의 원리

 
필자: 노찬형
빅터플랫폼 CIO. 대학에서 소프트웨어공학을 전공했으며 개발자로 사회 생활을 시작했다. 사회 생활 10년을 넘기고 시작했던 DB 공부가 프로그래머로서 자신을 분명하게 되돌아볼 수 있는 기회를 주었다. 사회 초년생 또는 대학생에게 도움이 되는 데이터 모델링 글을 쓰고 싶은 게 그의 작은 바람이다.

pemaker@gmail.com
 

주경야독하는 이들을 위해

우연한 일이 계기가 돼 필자는 DB와 데이터 모델링을 글로 정리할 수밖에 없는 상황에 맞닥뜨렸다. 필자는 2012년부터 2013년까지 한 대학에서 DB 강의를 했다. 강의를 요청받았을 때, 어떻게 해야 할지 난감했다. 필자가 맡은 반은 낮에는 일하고 저녁에 공부하는 학생들로 구성돼 있었다. 일반 대학생들처럼 많은 시간을 공부에 쓸 수 없는 학생들에 DB를 알려줘야 했다. 어떻게 하면 그들에게 작으나마 도움이 될까 하고 고민하던중 시중 교재 대신, 필자가 직접 강의 자료를 만들어 보면 좋겠다는 생각을 하기에 이르렀다.

물론 시중의 책이 부족해서 그런 것은 아니다. 필자가 자료를 직접 만들어 쓰면, 일반 책으로 했을 때보다 더 쉽게 소개할 수 있을 것 같아서 그랬다. 누가 보더라도 이해하기 쉽게 전달하겠다는 목표로 강의 자료를 만들기 시작했다. 2년 넘게 강의 자료를 준비하다 보니, DB의 기초와 데이터 모델링의 기초에 대한 내용을 어느 정도 만들어 낼 수 있었다.

학생들이 강의자료를 요청하면 줬다. 하지만 설명이 없는 프레젠테이션 문서라서 아쉬웠다. 설명이 추가되면 학생들이 예습/복습을 할 때도 훨씬 좋을 텐데…. 배웠거나 배울 학생들을 위해 프레젠테이션 문서를 글로 정리하기 시작했다. 말보다 글로 정리하는 게 더 어렵다는 걸 실감하는 순간의 연속이었다.

‘하늘 아래 새로운 건 없다’는 말처럼 필자의 강의 자료 역시 인식하든 못하든 수많은 자료와 가르침을 받았던 결과물들이다. 물론 보고 들었던 이론을 개발 현장에서 적용?확인하는 과정을 거친, 경험의 산물이다. 앞으로 몇 회에 걸쳐 ‘제로에서 시작하는 데이터 모델링’ 연재를 하겠다고 용기를 내보았다. 독자 여러분과 함께 쓴다는 생각으로 수많은 의견이나 접근 방법을 댓글 또는 이메일로 받을 수 있었으면 좋겠다.
 

지난회에 이어 속성에 대해 알아본다. 속성(attribute)은 세부적인 부품 또는 구성요소로서, 엔터티나 릴레이션십의 특성, 식별, 분류, 수량, 상태를 표현하기 위한 모든 세부사항이라고 소개했다. 이번 회에는 속성명 부여에 대해 알아본다.

• 속성 도출

모델러는 인터뷰, 관련 문서, 리포트, 장표, 정보 시스템의 DB 등을 통해 데이터 모델을 설계하고 속성을 도출한다. 모델러가 해당 도메인 업무 전문가라면 비즈니스를 완벽하게 이해하고 모든 속성을 도출할 수 있다면 좋겠지만, 하지만 현실은 그렇지 않은 경우가 많다. 따라서 책임은 모델러에게 있더라도 개발자나 협업 실무자들의 도움을 받아 도출해야 한다.


[그림 1] 모델 단계별 주요 업무
개념 모델링 단계에서는 업무적 의미 전달을 위해 엔터티와 식별자, 주요 속성을 도출한다. 논리 모델링 단계에서는 개념 모델을 기반으로 모든 속성을 원자성을 고려해 정의한다. 이때 논리적인 데이터 타입과 길이, 식별자 확정, 필수 여부 확정, 값의 범위나 지정값 정의, 속성의 도메인 지정 등의 작업을 한다.

물리 모델링에서는 논리모델을 기반으로 변환·반정규화를 한다.

 

• 속성 도출 가이드

속성을 도출할 때는 다음 부분에 유의해야 한다.

· 속성의 의미를 명확히 한다.
· 속성이 하나의 사실만 갖는지 확인한다.
· 원시속성인지 확인한다.
· 속성에 적절한 명칭을 부여한다.

1) 속성의 의미 명확화

속성은 속성이 무엇을 저장할 것인지와 저장 값은 어떻게 해석해야 할까?에 대한 질문을 통해 그 의미를 명확히 할 수 있다.


[그림 2] 주문내역의 속성
[그림 2]는 고객이 주문한 주문내역을 관리하는 엔터티다. 주문내역에는 주문번호, 고객번호, 주문금액, 주문상태, 우편번호, 주소 속성이 있다. 이 속성 중 주문금액은 어떤 데이터를 관리하는 속성일까?

단순히 생각하면 말 그대로 ‘고객이 주문한 주문금액’이라고 할 수 있다. 조금 더 생각해 보면 주문 상품들의 총금액인지, 단일 상품에 대한 주문금액인지, 할인이 적용된 금액인지, 할인이 적용되기 전 금액인지 명확하지 않다.

속성을 도출할 때는 속성명도 중요하고 속성이 갖는 의미와 무엇을 저장하고 그 값을 어떻게 해석해야 하는지도 중요하다. 정확한 의미로 정의되지 않는다면, 잘못된 이해와 사용으로 집합의 의미가 변질되거나 최종결과 값이 안 맞는 등의 오류로 연결될 수 있다.


[그림 3] 주문내역의 누락, 중복 속성
속성에 정확하고 구체적인 의미를 부여해야 정확하게 의미를 전달할 수 있다. 속성정의가 명확하면 누락된 속성과 중복 속성도 발견할 수 있다.

[그림 3]을 보면, 주문금액은 주문 상품들 가격의 총합이며 할인 전 금액임을 알 수 있다. 할인금액은 다른 엔터티에서 관리하고 있으므로, 주문내역 엔터티에서 누락된 것은 결제금액, 즉 주문금액에서 할인금액을 제외한 고객이 최종 결제한 금액이다.

2) 속성이 하나의 사실만 갖는지 확인

속성은 관계형 데이터 모델에서 가장 작은 단위로서 하나의 사실만을 가져야 한다. 이것을 속성의 원자성이라고 한다. 하나의 속성이 한 개 이상의 사실을 가지면 안 되며, 이는 제1정규화 위반이다(제1정규화 도메인의 원자성). 또한 하나의 속성에 하나의 사실, 즉 팩트만 관리한다. 이때 팩트는 비즈니스 관점에서 봐야 한다.


[그림 4] 최소 단위의 예
우리가 잘 알고 있는 전화번호로 알아보자. 전화번호는 [그림 4]와 같이 최소 단위로 분해해 관리할 수 있고, 전화번호 전체를 하나의 속성으로 관리할 수도 있다. 어떤 것이 맞는 것일까? 둘 다 맞다고 할 수 있다.

맞고 틀리고는 비즈니스 관점에서 봐야 한다. 전화사업자는 지역번호, 국번호, 개별번호 각각이 의미가 있으므로 최소 단위로 분리하여 관리할 것이다. 일반 기업에서 고객 전화번호를 관리하는 경우라면 하나의 속성으로 통합 관리하는 것이 일반적이다.

즉 비즈니스 요건에 따라 최소 단위로 분리해 관리해야 한다면, 최소 단위로 분리하는 것이 맞다. 무조건적인 물리적인 최소 분해는 잘못된 속성 도출로 연결될 수 있으므로 유의해야 한다.

속성의 원자성을 확인할 때는 다음과 같은 생각을 해보면 도움이 된다. 비즈니스 관점에서 하나 이상의 사실(fact)이 존재하는지, 속성의 일부만 변경되는 경우가 있는지, 속성의 일부 값에만 종속이 존재하는지, 속성의 일부만으로 정렬하는 경우가 있는지, 수식 연산 과정에서 복잡한 과정이 발생하는지를 살펴서 분리할지 합칠지를 결정하면 좋다.

3) 원시속성인지 확인

원시속성을 거론할 때 추출속성을 제시하면 쉽게 이해할 수 있다. 원시속성이란 다른 속성에 독립적으로 존재할 수 있는 원천적인 속성을 말한다. 추출속성이란 다른 속성을 기반으로 중복?가공?유도되는 속성을 말한다.

다음 예를 통해 알아보자.


[그림 5] 원시속성, 추출속성
[그림 5]는 고객과 고객의 결혼여부, 고객 중 회원의 접속내역을 관리하는 모델이다. 고객 엔터티의 결혼여부 속성을 보면 별 문제가 없어 보이지만 이는 추출속성이다. 고객이 결혼을 했는지 안 했는지는 고객결혼이력 엔터티의 데이터를 조회하면 알 수 있는데도 고객 엔터티에 결혼여부 속성을 중복으로 도출한 것이다.

두 엔터티의 데이터 발생에 따라서 속성 값의 변화를 생각해 보자. 고객이 처음 가입했을 때는 결혼을 하지 않아서 고객결혼이력에 데이터가 존재하지 않을 수 있다. 이때는 고객의 결혼여부는 아마도 N(미혼)으로 저장할 것이다. 이후에 고객이 결혼하게 되면 고객결혼이력에 데이터가 생성되므로 결혼여부가 Y(결혼)로 바뀌어야 한다. 즉 고객결혼이력에 의해 결혼여부가 종속적으로 바뀌는 것이다. 또 다른 측면으로 이야기해 보면, 고객결혼이력에 데이터가 생성되지 않고서도 결혼여부 속성의 데이터를 바꿀 수 있다.

이와 같은 예를 봤을 때, 추출속성은 데이터 정합성 훼손의 원인이 될 수 있다. 따라서 속성은 하나의 사실이 변경될 때, 하나의 원시속성이 변경되는 것이 이상적이다. 또한 추출속성을 사용하면 제2정규화(부분함수종속제거) 위반이 일어날 수 있다.

그런데 추출속성을 무조건 사용하지 않는 것은 아니다. 논리모델링을 할 때 성능 이슈 등으로 인해 추출속성을 도출해 사용하는 경우가 있다. 이때 추출속성의 유형은 여러 속성 중에서 하나를 선택(최초, 현재, 최종 등)하거나 여러 속성을 모아 그룹 연산(SUM, COUNT, AVG)하는 경우가 있다.


[그림 6] 추출속성
[그림 6]은 온라인 카페를 관리하는 모델이다. 온라인 카페 엔터티에 보면 카페회원수, 총게시물수, 금일방문자수, 최근7일방문자수가 추출속성이다. 이런 속성들은 다른 엔터티에서 조회하면 파악할 수 있다. 그렇더라도 화면을 열 때마다 총게시물수를 조회해 온다는 것은 매우 비효율적이고, 성능에 영향을 줄 수 있기에 추출속성을 사용하기도 한다. 따라서 추출속성은 실제로는 중복(redundancy)인 것은 맞지만 현실적으로 배제할 수 없기 때문에 꼭 필요한 곳에 적절히 사용해야 한다. 이때 언뜻 보기에는 추출속성 같은데 원시속성인 경우가 있으므로 주의해서 잘 살펴봐야 한다.

원시속성에 대해 소개한다 해놓고 추출속성에 대한 얘기만 했다. 추출속성에 대해 이해하면 원시속성은 자연스럽게 알 수 있다. 추출속성이 아니면 원시속성이니까 말이다.

논리 모델링을 할 때, 논리 단계에서 원시속성에 집중한다. 논리 단계라도 비즈니스 상 중요한 추출속성은 먼저 도출한다. 도출된 추출속성은 반듯이 원시속성과 관계를 정의해야 한다.

4) 속성에 적절한 명칭 부여

명칭에 대해 계속해서 거론했다. 사람에게 이름이 중요하 듯이 엔터티명이든 속성명이든 적절하고 명확하게 부여해야 한다.


[그림 7] 이상한 속성명
[그림 7] 고객 엔터티에 있는 속성 명칭을 보자. ID는 식별자이다. 그럼 고객구분과 고객유형은 무엇일까? SEQ는 sequence(일련번호)인 듯 한데 무엇을 의미하는 것일까? MAX구매액은 실제 구매액 중에서 가장 큰 값일까? 아니면 최대로 구매 가능한 금액일까? 등 많은 의문이 들 수 있다. 속성명에 속성정의가 있다면 그것을 보고 이해할 수 있을 것이다. 속성정의도 중요하지만 속성명도 명확하게 부여해야 한다.

속성에 명확한 이름을 붙이는 것은 곧 속성정의가 명확함을 의미한다. 따라서 꼭 속성정의와 일치되는 이름을 부여해야 한다.

속성에 이름을 부여할 때는 일반적으로 다음과 같은 기준을 따른다(이것은 모델러에 따라 데이터 표준에 다라 달라질 수 있다. 단지 필자가 주로 사용하는 방법 가운데 하나다).


[그림 8] 속성명 작성 가이드
속성명은 일반적으로 수식어+수식어+도메인으로 구성한다. 앞서 수식어는 WHAT으로 속성이 무엇이냐를 나타내며, 도메인은 분류를 나타낸다.

예를 들어 구매금액이라는 속성명은 구매라는 수식어와 금액이라는 도메인을 붙여서 만든 경우다(구매금액= 구매(수식어) + 금액(도메인)). 이때 수식어는 하나 이상일 수 있으며, 도메인은 속성이 어떤 분류?유형인지를 표현한다.

다음의 속성명을 보고 부족한 부분이 있으면 좀 더 좋은 속성명으로 바꿔보자.


[그림 9] 속성명 바꾸기 예제 1
[그림 9]를 보면, 고객·상품·수량·가격·할인·일자라는 속성명이 적합하게 부여된 것 같지는 않다. 오해의 소지가 있다. 할인은 할인금액인지 할인율인지 애매하다. 따라서 다음과 같이 바꿔보면 좀 더 명확한 속성명이 될 것이다.


[그림 10] 속성명 바꾸기 예제 2
[그림 10]은 상품은 상품NO, 수량은 주문수량, 가격은 주문가격, 할인은 할인율, 일자는 구입일자로 속성명을 바꾼 것이다. 바꾼 속성명과 데이터를 보면 [그림 9]보다 명확하게 이해할 수 있다. 이와 같이 속성명은 해당 데이터를 명확하게 표현할 수 있는 명칭으로 부여해야 한다. 속성명 부여 시, 내가 정의한 명칭을 다른 사람이 나와 똑같이 이해할 것이라는 생각을 늘 염두에 둘 필요가 있다.

 

• 속성부여 사례

1) 원자분해 실패

원자분해 실패는 하나의 속성에 2개 이상의 사실(fact)이 결합된 경우를 말한다. [그림 11]의 주문수량 속성의 수량이 일반적으로 짐작할 수 있는 개수를 말하는 것인지, 아니면 다른 의미를 갖고 있는지 정확한 의미를 살펴봐야 한다.


[그림 11] 단위가 생략돼 원자분해에 실패한 사례
[그림 10]과 [그림 11]의 주문수량은 단위가 생략돼 있고, 2개 이상의 사실(fact)이 결합된 하나의 속성이다. 속성을 볼 때는 비즈니스 의미를 갖는 가장 작은 조각으로 분리됐는지, 속성의 일부(수량이나 단위)만 변경될 수 있는지, 속성의 일부만으로 정렬이 필요한지, 속성 값으로 수식 연산이나 비교가 용이한지 등을 잘 살펴봐서 [그림 11]의 주문수량과 같이 2개의 사실이 결합되지 않도록 해야 한다.

2) 다중 의미 코드 세트

다중 의미 코드 세트란 하나 이상의 코드(code)가 결합된 하나의 속성을 말한다.


[그림 12] 다중 의미 코드 속성 예
[그림 12] 사원구분코드에 S, M, T의 값이 들어가 있다. S는 우리사원이면서 기술직, M은 우리사원이면서 매니저, T는 협력사원이면서 기술직을 의미한다.

이렇게 속성 값은 우리사원 + 기술직 등 다중 의미 코드가 결합된 값을 쓰는 것을 지양해야 한다. 이렇게 사용하면 우리 사원만 조회하거나, 기술직만 조회하는 경우 SQL이 복잡해진다. 협력사원?매니저라는 속성이 추가되면 새로운 값을 만들어 내야 하지만, 코드 인스턴스가 추가될 때마다 SQL 수정이 필요할 수 있다. 따라서 속성은 하나의 의미를 가져야 하기 때문에 [그림 12]의 경우는 속성을 2개로 나눠주는 것이 바람직하다.

다음 연재에서는 식별자에 대해 알아보겠다. (다음 회에 계속)

 

출처 : 한국데이터산업진흥원

제공 : 데이터 전문가 지식포털 데이터온에어(dataonair.or.kr)