오늘은 이력관리에 대해서 이야기 해보려고 합니다.
데이터 모델링을 하다보면, 중요한 데이터에 대해서 변경이 일어날때, 이전의 모습이 어땠는지를 기록해 두어야 할 필요가 생기구요. 이때 변경에 대한 이력을 기록하기 위한 데이터 모델을 작성하게 되죠.
이러한 이력을 어떻게 모델링 할 수 있을까요?
일단 데이터의 건수가 많지 않으면서 변경도 그다지 자주 발생하지 않는 경우는 하나의 테이블 내에서 최종 데이터와 이력 데이터를 아래와 같이 간단하게 함께 관리할 수 있습니다.
이전키를 가지기 위해서 자기참조관계를 맺어주게 되구요. 이력을 빼고 최종만 조회하기 위해서 최종여부를 두는 것이 편리합니다.
그런데, 데이터 건수도 많고 변경도 자주 일어나는 경우라면 이력 테이블을 별도로 분리해야 하구요. 사실 이게 훨씬 더 일반적인 모습입니다.
이때에는 일반적인 업무에서는 왼쪽 사원 엔터티에만 접근하게 되고, 한달 전 같은 특정 시점의 데이터를 보려고 할때에는 오른쪽 이력 엔터티에 접근하게 됩니다. 명확하게 분리해서 사용하게 되죠.
여기서 가만히 조금만 더 생각해보면, 변경이 일어날때 사원의 모든 컬럼의 값이 바뀌는 것은 아닐텐데, 그걸 다 기록해 두는 것이 -바뀌지 않는 정보도 기록해 두는것이- 저장 공간이 아까울 수 있습니다. 이럴때는 변경이 일어난 컬럼만 뽑아서 이력에 기록하는 식으로 개선할 수 있습니다.
사원 엔터티의 컬럼숫자는 매우 많으면서 한번에 변경되는 컬럼은 한두개인경우 이런 모델은 빛을 발하게 됩니다. 게다가 이 모델을 조금 확장하면 여러개의 엔터티의 이력을 한꺼번에 모아서 관리할 수도 있습니다.
지금까지 이력을 정리하기 위한 여러가지 모델을 살펴 봤습니다. 설명에서 느끼셨겠지만, 정답이 없습니다. 그때그때 상황에 맞는 선택이 있을 뿐이죠.
그런데 지금까지의 이력 모델링은 "한 건의 데이터가 변경되더라도 여전히 한 건이다"라는 전제하에서 작성되었다고 할 수 있습니다. 예를 들어 손오공 이라는 사원의 주소가 변경된 경우 손오공이라는 실체는 하나라는 점에는 변함이 없고, 변경 전 후 데이터가 발생하는 것이죠. 그런데 만일 손오공씨가 어느날 임원이 되었는데, 회사 규정상 사원으로써의 손오공과 임원으로써의 손오공 두 건의 데이터를 관리해야 한다면 어떻게 해야 할까요? 또 임원 직위를 상실하게 되는 날 다시 사원으로써의 데이터만 남겨져야 한다면요? (손오공이 머리털을 뽑아 분신술을 한다는 점에 착안해서 일부러 손오공으로 이름을 적어봤습니다. :-p )
위의 모델들에서는 이와같이 변경시 데이터가 분할되거나 합병되는 경우를 다루기가 어렵습니다. 이럴때의 이력은 변경 전후를 원테이블과 두 개 이상의 관계로써 표현해야 가능합니다.
이력관리 모델은 우리 주변에서 흔히 찾아볼 수 있는데요, 그중에서 제가 자주 발견하는 오류를 두가지 정리해봅니다.
첫번째로는 이력이 아닌 엔터티도 이력이라는 이름이 포함되어 있으면서 이력 데이터라고 생각하는 경우를 들 수 있습니다. ( 언제 날잡아서 엔터티 명이나 속성 명이 잘못된 사례들도 정리해서 올려볼께요. )
예를들어 "사원평가이력" 라는 엔터티 명이 있습니다. 이것은 정말 이력일까요?
Q: 이력 이라는 단어를 빼고 엔터티 명을 읽어봐도 잘 이해가 되고 해당 엔터티를 잘 설명하고 있다면 ?
A: 이력 엔터티가 아닐 확률 99 퍼센트 입니다!
Q: 최종 데이터만 모여있는 이력을 파생시킨 원조 엔터티가 별도록 존재 한다면?
A: 이력 엔터티일 확률 100% 입니다.
Q: 속성 중에 변경 전/후 의미하는 속성 세트 들이 있다면?
A: 이력 엔터티 일 확률 90% 입니다.
Q: 속성중에 수정일시, 변경일시 속성이 있나요?
A: 이력 엔터티 일수도, 아닐수도 있습니다.
일반 엔터티 중에도 최종적으로 수정된 일시를 기록하는 엔터티는 많이 있거든요.
이상의 질문들로 확인해 봤을때, 사원평가이력 엔터티는 이력이 전혀 아니었습니다.
단지 담백하게 사원평가 엔터티 였죠.
둘째로는 하나의 엔터티에 대한 변경이력을 유형에 따라 분리하는 것은 가급적 피하라는 것입니다.
이력의 유형을 분리한다는 것은 예를들면 다음과 같이 모델링 된 것인데요.
이력의 중요한 용도 중 하나는 과거 특정 시점의 모습을 다시 확인하는 것입니다. 그런데, 이렇게 이력이 여러 엔터티에 분산되어 있다면, 재현 용도의 사용이 매우 어려워 집니다. 양쪽 이력 엔터티를 뒤져서 특정 시점 이전의 변경내용을 모두 살펴서 합쳐야 하니까요.
만약 분할된 이력 엔터티 들이 저 위해서 설명했던 변경된 컬럼만 기록한 모델 형태라고 까지 가정하고, 과거 특정 시점의 모습을 재현하는 SQL을 만든다고 생각해보면 아마 아~ 이렇게 하면 안되겠구나 생각하실 거에요. ;-)
오늘은 중요한 데이터의 변경을 기록해 두기 위한 이력 모델링의 다양한 방법과 주의사항에 대해서 살펴 봤습니다.
'Data Modeling' 카테고리의 다른 글
속성이냐 엔터티냐 (0) | 2013.05.10 |
---|---|
서브타입 해체하기 (0) | 2013.05.01 |
공통 데이터 다루기 (0) | 2013.04.18 |
서브타입 사용하기 (0) | 2013.04.13 |
엔터티 분할하기 (0) | 2013.04.06 |