관계형 데이터 모델링 노트 : 06 이력 데이터 이야기
Chapter 6 : 이력 데이터 이야기
서론
- “관계형 데이터 모델링 노트” 책을 통해 진행한 이론 스터디 여섯번째 시간이다.
이력 데이터는 지나간 데이터이다. 원천 데이터가 수정되거나 변경돼야 이력 데이터가 생긴다. 단지 과거 데이터를 이력 데이터라고 하지 않는다. 언제 입력되었든 입력된 데이터가 변경되어야 이력 데이터 이다.
이력 데이터에 대한 서설
-
이력 데이터가 명확하기 위해서는 원천 데이터가 명확해야 한다. 이력데이터는 원천 데이터에 종속되어 있기 때문이다.
-
이력 엔티티가 원천 엔티티에 종속됐다는 점은 원천 데이터가 바뀌는 것이 이력 데이터라는 것을 의미한다. 원천 데이터가 생기는 것을 이력 데이터라고 하지 않는다. 이미 존재하는 원천 데이터가 바꿔야 이력 데이터가 된다.
-
이력 데이터를 관리해야 하는지는 현업의 요건으로 판단하는 것이 원칙이지만, 간혹 모델러가 판단할 필요가 있다. 가능하면 주요 엔티티는 이력 데이터 관리 요건이 생길 것을 대비하는 것이 좋다.
이력 데이터와 내역 데이터
-
이력 데이터란 변경된 데이터다. 예전에 쌓인 데이터여도 변경되지 않았다면 이력 데이터가 아니라 내역 데이터다.
-
이력 데이터는 단순히 쌓여 있는 과거의 데이터가 아니라 변경된 과거 데이터이다. 현재(원천) 데이터를 다루고 있다면 내역 데이터일 가능성이 높다. 원천 데이터를 이력 엔티티에서 관리한다면 내역, 이력으로 엔티티를 쪼개는 것이 좋다. 다만 모델러의 성향에 따라 내역+이력 엔티티로 설계하는 경우도 있다. 이는 엔티티를 줄일 수 있다는 장점이 있다.
이력 엔티티 설계 시점
-
원천 엔티티 설계 시 이력 엔티티 설계
- 본질이 정의되는 시점이라 이력 엔티티 떄문에 혼란이 생길 수 있음. -
물리 모델링 시점에 이력 엔티티 설계
- 이력 엔티티에 따라 원천 엔티티 구조가 변경될 수 있어서 물리 모델링 단계에서는 변경 부담이 크다.
- 모델링 기간이 짧은 경우, 본질 데이터를 정의하고 이력 데이터를 나중에 정의하면 시간이 오래 걸리기 때문에 이런 경우는 한번에 설계해야 한다.
이력 데이터를 설계하는 방법
-
엔티티 단위 이력
- 엔티티 전체 속성 변경에 따른 이력 생성 -
속성 단위 이력
- 변경된 속성의 데이터만을 별도로 관리하는 방법 -
속성 그룹 단위 이력
- 속성 중 유사하거나 같이 사용되는 속성을 묶어서 별도의 엔티티에서 이력 데이터를 관리하는 방법
이력 데이터를 설계하는 첫번째 방법 - 엔티티 단위
- 엔티티 단위로 이력 데이터를 설계하는 방법은 다시 두 가지로 나눌 수 있다. 이력 데이터를 별도의 엔티티에서 관리하는 방법이 있으며, 이력 데이터와 원천 데이터를 함께 관리하는 방법이 있다.
1. 이력 데이터를 별도 엔티티로 설계하는 방법
-
아래와 같이 원천(내역) 데이터와 변경(이력) 데이터를 별도로 관리하면 이력 데이터를 생성하는게 다른 방법에 비해 쉽다는 점이다. 또한 원 데이터를 관리하기 수월하다. 하위 엔티티에 미치는 영향도 차단했기 때문에 모델이 안정적이다.
-
반면에 거의 유사한 스키마의 엔티티를 동일하게 유지해야 하는 점은 부담이다. 원천 엔티티에 속성이 추가되면 이력 엔티티에도 속성을 추가해 줘야 한다. 또한 엔티티가 늘어 난다는 부담도 있다.
- 실체 엔티티
-
원천 데이터를 관리하는 계좌 엔티티는 변경 없이 그대로 존재하며, 이력 데이터는 원천 엔티티와는 별도의 엔티티인 계좌 이력 엔티티에서 관리한다.
-
데이터도 변경 값만 관리하는 방법과 중복 데이터로 관리하는 방법이 있다. 중복 데이터를 사용하는 방법은 원천 데이터와 이력 데이터를 동시에 조회하는 요건이 많은 경우 사용하는 방법이다. 중복 데이터를 사용하는 방법은 비정규화의 일종이다.
-
- 기준 엔티티
- 환율 데이터와는 별도로 환율 이력 엔티티에서 변경된 이력 데이터를 관리한다. 환율 엔티티에 현재의 환율과 과거 환율 데이터가 존재하고 환율 이력 엔티티에는 변경된 환율 데이터가 존재한다. 과거(오늘 이전) 환율이 변경되는 경우는 드물어서 환율을 이처럼 관리하는 업무는 드물다.
- 만약에 환율 데이터를 현재(해당일)의 환율만 관리하는 엔티티라면 아래와 같이 관리할 수 있다.
- 행위 엔티티
-
주문 엔티티의 속성값이 변경되는 경우는 이력 관리는 아래와 같이 관리할 수 있다.
-
만약에 주문 엔티티의 속성은 변경되지 않고 주문 상품 엔티티의 속성만 변경된다면 아래와 같이 관리한다.
-
주문/주문상품 엔티티 모두가 변경될 가능성이 있다면 아래와 같이 관리한다. 원천 엔티티가 종속 관계 모델이면 이력 엔티티도 종속 관계 모델이어야 한다.
-
- 실체 엔티티
2. 하나의 엔티티에서 원천 데이터와 변경 데이터를 관리하는 방법
-
이 방법은 실체 엔티티와 기준 엔티티에서 간혹 사용된다. 행위 엔티에서는 거의 사용되지 않는다.
-
하나의 엔티티에서 원천 데이터와 변경 데이터(이력)를 같이 관리하는 주요한 이유는 변경 데이터에 대한 사용 빈도가 높기 때문이다. 변경 데이터가 빈번하게 사용되고, 원천 데이터와 동시에 사용된다면, 하나의 엔티티에서 관리하는 것이 효율적이다. 반면에 원천 데이터만 사용하고 변경 데이터는 거의 사용되지 않는다면 원천/이력을 따로 관리하는 것이 좋다.
-
하나의 엔티티에서 이력 데이터까지 관리하면 데이터 모델을 관리하기 편하다. 또한 엔티티 개수를 줄이는 효과를 낼 수 있다.
-
원천 데이터와 변경 데이터를 한 엔티티에서 관리하면, 엔티티의 성격이 불명확해지는 경향이 있다.
- 실체 엔티티
- 원천 데이터를 관리하는 엔티티에 이력 데이터를 혼합하여 관리하는 기본적인 모델은 아래와 같다.
- 원천 데이터를 관리하는 엔티티에 이력 데이터를 혼합하여 관리하는 기본적인 모델은 아래와 같다.
- 기준 엔티티
- 기준 엔티티는 결과적으로 이 방법을 사용해서 이력 데이터를 설계하는 경우가 많다. 변경되기 전의 환율을 관리해야 할 때, 변경 데이터를 하나의 엔티티에서 관리한다면 아래와 같이 설계 가능하다.
- 기준 엔티티는 결과적으로 이 방법을 사용해서 이력 데이터를 설계하는 경우가 많다. 변경되기 전의 환율을 관리해야 할 때, 변경 데이터를 하나의 엔티티에서 관리한다면 아래와 같이 설계 가능하다.
- 행위 엔티티
-
원천 데이터를 관리하는 주문 엔티티에 변경 데이터를 함께 관리한다면 아래와 같이 변경일자 속성이 추가된다.
-
이 모델의 문제는 주문 엔티티의 하위 엔티티가 존재한다는 것이다. 둘은 종속 관계이기 때문에 식별자가 상속된다. 하위 엔티티가 없더라도 행위 엔티티에는 많은 속성과 인스턴스가 존재하기 때문에 많은 중복이 발생하여 바람직하지 않는다.
-
- 실체 엔티티
이력 데이터를 설계하는 두번째 방법 - 속성 단위
- 속성 단위로 이력 데이터를 설계하는 방법도 역시 두가지로 나눌 수 있다. 변경 데이터를 별도의 엔티티에서 관리하는 방법과 변경 데이터를 원천 데이터와 함께 관리하는 방법이 있다.
1. 별도의 엔티티로 관리하는 방법
-
아래 와 같이 속성 하나에 대해서만 이력 관리하고, 현재 유효한 데이터와 무효한 데이터를 별도로 관리하는 방법의 가장 커다란 특징은 엔티티 성격이 명확해진다. 이는 모델의 확장성이 좋아진다는 것을 의미한다. 반면에 모델링을 정밀하게 해야 되어서 모델링이 어려울 수 있다. 요건을 정밀하게 분석해야 해서 시간이 오래 걸린다.
-
속성 단위로 이력 엔티티를 별도로 설계하는 방법은 실무에서 많이 사용하지 않는다. 요건을 도출하기 어렵고 상세한 모델링을 해야 하기 때문이다.
2. 변경 데이터와 원천 데이터를 함께 관리하는 방법
- 특정 속성의 원천 데이터를 별도의 엔티티에서 관리하면서, 변경 데이터와 원천 데이터를 함께 관리하는 방법이다.
이력 데이터를 설계하는 세번째 방법 - 속성 그룹 단위로 관리
-
속성 그룹 단위로 이력 데이터를 설계하는 방법은 하나의 속성 단위로 이력 설계하는 방법과 기본적으로 같다.
-
속성 그룹으로 묶을 수 있는 속성은 성격이 유사한 속성을 의미한다. 도메인 유형이 같은 속성을 그룹으로 묶기도 한다. 또한 주로 같이 조회되는 속성, 동시에 입력되는 속성을 그룹으로 묶을 수도 있다.
-
속성 별로 하나의 엔티티에서 관리하는 방법은 엔티티가 늘어나는 단점이 있지만, 이 방법은 엔티티도 많이 늘어나지 않는다. 모델로 업무 파악하기에도 비교적 좋아 적절하게 사용하면 효율적인 모델이 된다. 모델로 업무 파악하기도 비교적 좋으며 효율적인 모델이 된다. 반면에 명확한 기준이 없으면 원천과 이력의 성격이 혼란스러울 수 있다.
-
아래 모델의 경우 계좌의 비밀번호를 속성 그룹으로 이력 관리를 한다. 값이 변경될 때 그 시점의 데이터를 그대로 이력 데이터로 쌓는 방법과 변경되지 않는 데이터를 Null로 저장하는 방법 두가지다.
이력 데이터를 설계하는 네번째 방법 - 종테이블로 관리
-
위에서는 이력데이터를 설계하는 방법에 3가지로 라고 했지만 이와 같이 종테이블로 관리하는 방법이 하나 더 있다. 다만 이 방법은 설계하기 가장 쉬운 방법이다. 하지만 정형화되서 표면적으로 쉬워 보일 뿐 데이터를 제대로 관리하기 쉽지 않다.
-
원천 엔티티에서 변경된 속성을 종 테이블(Vertical Table) 형식의 별도 엔티티에서 통합 관리하는 것이 이 방법의 특징이다. 또한 이력 설계 대상 속성은 별도의 엔티티에서 기준 정보로서 관리한다. 이 방법에서는 일반적으로 원천 엔티티의 모든 속성이 이력 관리 대상 속성이다.
-
이 방법의 가장 큰 문제점은 보통 계좌 이력 엔티티에서 관리할 속성이 명확하지 않다는 것이다. 또 다른 문제는 인스턴스 전체를 쌓는게 아니기 때문에 특정 시점의 모든 속성 데이터를 조회하기 여럽다는 것이다.
-
종 테이블을 사용하는 것은 모델 구조가 데이터 속으로 사라지기 때문에 제대로 사용하기 쉽지 않다.
-
이 방법의 최대 장점은 모델을 형상 관리할 필요가 없다는 점이다. 그만큼 유연한 구조의 모델이다. 그리고 변경된 개별 속성을 조회하기는 쉬운 편이다. 저장 공간도 적게 사용하며 설계하기 편하다는 장점이 있어 실무에서 많이 사용한다.
이력 데이터를 종 테이블로 설계하는 다양한 방법
선분 이력의 종료 일자
-
선분 이력 방법은 심각한 성능 문제가 없다면 사용하지 않아야 한다. 즉 종료 일자와 시작 일자를 사용하는 대신 변경 일자를 사용해야 한다.
-
종료 일자를 사용하는 것은 몇가지 문제가 있다. 가장 큰 문제는 종료 일자 속성이 추출 속성이라는 것이다. 만약에 시작일자와 종료일자를 연결해서 선분이 되지 않는다면 무결성이 깨질 수 있어서 문제가 된다.
-
추출 속성인 종료 일자 속성은 보수적으로 사용하는 것이 좋으며, 무의식적으로 사용하는 것은 지양해야 한다.
이력 엔티티의 주 식별자
- 선분 이력 모델에서 시작 일자와 종료 일자 속성 중에 어떤 속성이 주 식별자에 포함돼야 하는지에 대한 이견이 있다. 이에 판단은 성능 관점에서 이루어져야 한다. 그에 따라 종료 일자를 PK 선행 컬럼으로 두는 것이 좋다. 다만 이 방식은 주 식별자 값에 업데이터가 발생한다.
이력 엔티티 설계 절차
서브타입의 이력 모델
-
일반적으로 서브타입은 전체 모델에서 핵심적인 엔티티에 해당하기 때문에 제대로 설계해야 한다.
-
가장 일반적으로는 아래와 같이 설계한다. 이 모델의 경우는 서브 타입별로 이력 데이터를 관리할 수 있다. 이 모델은 슈퍼 타입과 서브 타입 별로 이력을 조회하는 경우 효과적이다.
-
다만 참조 무결성 제약을 생각하면 아래와 같은 모델로 설계하는 것이 원칙이다. 인스턴스 관리하기 떄문에 하나가 변경되면 전체 인스턴스를 스냅샷 형태로 관리하는 것이 바람직하다.
-
인스턴스 레벨이 아니라 특정 속성 단위로 이력을 관리하는 경우 아래와 같은 모델이 된다.
정정 데이터
-
정정 데이터는 이미 존재하는 데이터가 잘못되어 수정한 데이터다. 이력 데이터와 마찬가지로 변경된 데이터이지만 잘못을 정정한 데이터를 의미한다. 실무에서는 가끔 이력과 정정 데이터를 함께 관리해야 하는 요건이 발생한다.
-
정정 데이터와 이력 데이터를 혼용해서 사용하면 모델 구조가 이상해서 가독성이 떨어지거나 모델이 잘못 사용될 수 있다. 정정 데이터와 이력 데이터는 구분해서 관리하는 것이 바람직하다.
-
정정 데이터를 관리하는 방법은 몇가지 있다. 가장 간단한 방법은 기존 데이터를 정정해야 하는 데이터로 업데이트하는 것이다.
-
또는 이와 같이 이력 데이터와 동시에 관리 가능하다.
댓글남기기