6.1. 이력 데이터(Altered Data)에 대한 사설
- 내역데이터와 이력 데이터를 구별해서 사용
- 이력 데이터가 명확하기 위해서는 원천데이터가 명확해야 한다
- 이력데이터 관리는 현업의 요건으로 판단하지만, 주요 엔터티는 이력 데이터 관리 요건이 생길 것을 대비
6.2. 이력 데이터와 내역 데이터
- 필자는 이력과 내역을 변경이력과 발생내역이라는 용어로 구분
- 이력 데이터
- 단순히 쌓여있는 과거의 데이터가 아니라 변경된 과거 데이터
- 변경돼 유효하지 않은 데이터
- 내역 데이터
- 그림 6.1 주문 데이터를 관리하는 모델
- 하루에 같은 상품을 한번만 주문할 수 있다
- 주식별자 : 고객번호, 상품번호, 주문일자
- 주식별자는 인스턴스를 생성하는 기준
- 주문 엔터티는 주식별자대로 데이터가 쌓이기 때문에 내역 엔터티면서 원천 엔터티
- 그림 6.1 모델에 대한 이력 관리 모델
!그림6.1 모델에 대한 이력 모델.gif!- 하루에 같은 상품을 여러개 주문할 수 있다
- 이전 주문의 주문수량을 관리한다
- 그림6.2 이력 모델에 대한 릴레이션
- 주문엔터티의 주문수량 속성은 현재 유효한 속성
- 주문이력 엔터티의 주문수량은 유효하지 않은 속성
| | |
| - 상품엔터티의 상품가격속성은 현재 상품가격을 관리
| |
| - 상품가격이력엔터티의 상품가격속성은 현재 유효하지 않은 상품가격을 관리
| |
- 학력관리 모델
- 학력 엔터티의 주식별자인 고객번호와 졸업년도에 따라 생성되는 내역 엔터티
- 주문관리 모델 - 오른쪽 그림 수정 필요 - 그림6.12 내역 엔터티와 이력 엔터티를 별도로 관리하는 모델
6.3 이력 엔터티 설계 시점
- 개념/논리 모델링 시점에 이력 엔터티 설계
- 장점 : 이력 엔터티 설계로 인한 본질 엔터티의 영향을 최소화할 수 있다
- 단점 : 본질 엔터티와 이력 엔터티가 불명확해질 수 있다
- 물리 모델링 시점에 이력 엔터티 설계
- 장점 : 본질 엔터티의 설계에 집중할 수 있다
- 단점 : 이력 엔터티의 설계가 본질 엔터티에 영향을 줄수 있다
- 저자의 의견
- 논리 모델링 시점에 이력 엔터티 설계
- 모델링은 주요 엔터티에 대하여 업무식별자, 주요핵심속성, 이력데이터 관리 방안,성능 이슈등을 종합적으로 분석,판단
- 이력 엔터티를 설계할때는 선분이력을 고려해야 한다(식별자가 달라질 수 있다)
6.4 이력 데이터를 설계하는 방법
- 엔터티 단위 이력 관리
- 본질 엔터티의 속성값이 하나라도 변경되면 변경 전의 전체 속성을 이력 엔터티에서 관리하는 방법
- 저장하기가 쉽고, 해당 시점의 전체 데이터(변경된 속성값,변경되지 않은 속성값)를 조회하는데 유리
- 저장 공간의 낭비가 심하다
- 변경된 속성 값만을 조회하기가 어렵다
- 특정 시점의 전체 속성값을 조회하는 요건이 많을 때 유리
- 속성 단위 이력 관리
- 변경된 속성의 데이터만을 별도로 관리하는 방법
- 저장 공간 절약에 유리
- 변경된 속성이 무엇인지 명확히 알 수 있다
- 변경된 속성값과 변경되지 않은 속성값을 같이 조회하기가 불리
- 변경된 속성값을 조회하는 요건이 많을 때 유리
- 속성 그룹 단위 이력 관리
- 속성중 내용(도메인)이 유사하거나, 같이 사용될 수 있는 속성을 묶어서 이력 엔터티로 관리하는 방법
- 엔터티 단위로 관리하는 방법과 개별 속성 단위로 관리하는 방법의 장점을 수용한 방식
- 엔터티의 성격과 업무요건, 중요도에 맞춰 적절한 방법을 사용해야 한다
6.5 이력 데이터를 설계하는 첫 번째 방법
- 계좌 엔터티의 속성 중에서 하나라도 변경되면 변경 당시의 데이터를 스냅샷 형태로 계좌이력 엔터티에 생성한다
- 변경된 속성의 값은 원천 엔터티인 계좌 엔터티에 갱신한다
- 업무 요건이 본질 데이터와 변경 데이터가 같이 조회되는 경우가 드물 때 유리
- 계좌 엔터티(실체 엔터티)는 하위 엔터티가 많이 존재하기 때문에 별도의 엔터티에서 관리하는 것이 바람직한다
| |
- 주문 엔터티의 속성이 변경되면 그 시점의 데이터를 주문이력 엔터티로 인서트하고, 변경해야 할 속성은 주문엔터티에 업데이트
| - 주문상품 엔터티의 속성이 변경되면 그 시점의 데이터를 주문상품 이력 엔터티로 인서트하고, 변경해야 할 속성은 주문상품엔터티에 업데이트
|
- 행위 엔터티 중에서 그림6.23모델과 같이 종속관계인 경우
- 이력 엔터티도 본질 엔터티와 마찬가지로 종속관계로 모델
- 이력 엔터티간에도 물리적인 참조 무결성 관계가 존재해야 한다
- 주문엔터티의 속성이 변경되면 주문이력 엔터티에만 이력 데이터를 생성
- 주문상품엔터티의 속성이 변경되면 주문이력 엔터티와 주문상품이력 엔터티 모두에 이력데이터를 생성
6.6 이력 데이터를 설계하는 두 번째 방법
- 하나의 엔터티에 원천 데이터와 변경 데이터를 함께 관리
| | |
- 이력 데이터를 설계할 때는 먼저 본질 엔터티를 설계한다
| - 변경일자 속성은 논리적인 의미를 부여해서 사용하는 속성
| |
| - 논리적으로 널(null)값이어서 주식별자로 적당하지 않다
| |
| - 실체 엔터티인 경우 주식별자로 일자속성 사용은 드물다
| |
- 두 엔터티의 관계가 존재 종속관계
- 주문상품 엔터티의 변경일자 속성의 의미가 모호하다
- 데이터 중복이 많이 발생하여 행위 엔터티에서는 바람직한지 않다
- 발생내역과 변경이력을 같이 관리하기 때문에 엔터티의 성격이 불명확하다
- 데이터 모델을 관리하기가 좋다
- 원천 데이터와 변경 데이터를 같이 조회하는 요건이 매우 중요할 때 사용
6.7 이력 데이터를 설계하는 세 번째 방법
- 속성 단위로 이력 데이터를 관리하며, 별도의 엔티티에서 이력을 관리하는 방법
- 계좌 엔터티의 계좌비빌번호 속성에는 현재 비밀번호를 관리
- 계좌 이력 엔터티에는 유효하지 않은 비밀번호를 관리
- 계좌비밀번호 속성이 계좌 엔터티의 기초속성이긴 하지만, 개별적으로 자주 사용되고 중요하게 사용돼서 별도의 엔터티로 설계한 모델
- 계좌비밀번호 엔터티는 내역 엔터티이고, 계좌비밀번호이력 엔터티는 변경이력을 관리하는 엔터티
- 여러 비밀번호를 관리하기 위해 정규화한 모델
- 비밀번호구분코드 속성은 여러 비밀번호를 구분하기 위해서 사용
- 변경된 속성만 조회하는데 유리
6.8 이력 데이터를 설계하는 네 번째 방법
- 특정 속성의 원천 데이터를 별도의 엔티티에서 관리하면서 변경 데이터와 원천 데이터를 함께 관리하는 방법
- 계좌 비밀번호만을 관리하는 모델
- 계좌비밀번호 속성이 자주 중요하게 사용돼서 계좌 엔터티와 일대일 관계의 별도 엔터티로 설계한 모델
- 원천 모델에 대한 이력 관리 모델
- 계좌비밀번호 엔터티에서는 현재 유효한 비밀번호와 변경된 비밀번호를 같이 관리한다
| |
- 계좌비밀번호가 처음에 입력되고, 그 후에는 변경된 것으로 보는 모델
| - 계좌비밀번호가 처음에 입력되고, 비밀번호가 변경될때도 입력으로 보는 모델
|
- 그림[6.49] 변경일자는 변경되지 않았음(현재 유효한 비밀번호)을 의미하는 '9999-12-31'이다
- 그림[6.49] 비밀번호는 자주 사용되는 속성이라 현재의 비밀번호를 바로 알 수 있어 유리
- 그림[6.51] 모델은 자주 사용되지 않는 속성을 대상으로 사용하면 유리
- 유형별 이력 관리 모델
- 계좌와 관련된 비밀번호가 여러 개 인경우의 모델
6.9 속성 단위의이력 모델과 추출 속성
- 속성 단위로 이력 데이터를 설계한 모델에 추출 속성이 사용된 모델
- 속성 단위로 이력 데이터를 설계하는 방법은 역할을 관리하는 엔터티를 설계할 때 자주 사용
- 계좌관리사원 엔터티는 계좌 엔터티에서 계좌관리사원번호 속성을 별도로 관리하는 원천 엔터티
- 계좌 엔터티와 일대일 관계며 현재 유효한 계좌관리사원을 관리
- 계좌관리사원 엔터티처럼 별도의 엔터티로 관리하는 이유는 역할이 한 개가 아니라는 사실과 이력 데이터까지 고려한 모델
- 그림6.57 계좌엔터티와 계좌관리사원간 1:M 관계로 수정필요
| |
- 계좌를 관리하는 현재 유효한 사원과 이전에 관리했던 사원을 함께 관리
| - 계좌를 관리하는 현재 유효한 사원과 이전에 관리했던 사원을 함께 관리
|
| - 비정규화로 성능 문제 해결(계좌 엔터티에 현재계좌관리사원 속성을 관리-추출속성)
|
- 계좌관리사원이력 엔티티명 수정필요
- 계좌 엔터티에서 현재 유효한 관리사원만 관리하고, 변경된 관리사원은 계좌관리사원 엔터티에서 관리하는 모델
- 계좌관리사원이력 엔터티에는 ~이력을 붙여주고, 계좌관리사원번호 속성은 추출 속성이 아님('현재'를 붙일 필요 없음)
- 계좌관계사원 엔터티에서 여러 역할을 통합해서 관리하는 모델
- 엔터티명과 속성명이 더 일반적인 용어(관계사원)를 사용 - 엔티티명 수정 필요
| |
- 현재 유효한 데이터와 지난 데이터를 같이 관리
| - 특정 역할을 하는 현재 유효한 데이터를 중복으로 관리하는 모델
|
6.10 속성 그룹 단위로 이력 데이터를 설계하는 예제
- 성격이 유사한 속성, 도메인 유형이 유사한 속성을 속성그룹으로 묶어서 이력으로 관리하는 방법
- 계좌 엔터티의 계좌비밀번호와 ARS비밀번호 속성은 유사한 속성
- 계좌 엔터티의 유사한 비밀번호 속성을 속성 그룹으로 묶어서 이력 데이터를 설계
- 속성그룹중에 하나라도 변경되면 그 시점의 속성을 이력 데이터로 쌓고, 새로운 비밀번호는 계좌 엔터티에 업데이트
- 속성그룹에 속한 속성들을 같이 조회될 가능성이 있는 경우
- 같이 사용되는 속성을 그룹으로 묶은 모델(우편번호,우편주소,상세주소)
- 현재 유효한 주소는 고객 엔터티에서 관리하고, 유효하지 않은 주소는 고객주소이력 엔터티에서 관리
- 그림6.70 : 현재 유효한 주소는 고객주소 엔터티에서, 유효하지 않은 주소는 고객주소이력 엔터티에서 관리
- 그림6.71 : 유효하지 않은 과거의 주소를 빈번하게 사용하는 요건의 모델
- 도메인이 유사한 속성을 묶어서 이력 엔터티를 설계
- 주식종목 엔터티에서 묶은 속성을 별도의 엔터티에서 관리
- 그림 6.73 : 자주 사용하는 현재 유효한 데이터만 별도의 엔터티에서 관리하므로 유효한 데이터를 사요하기 수월
- 그림 6.74 : 현재 유효한 데이터와 변경 데이터가 주로 함께 사용되는 요건의 모델
6.11 이력 데이터를 설계하는 다섯번째 방법
- 원천 데이터에서 변경된 속성을 종 테이블 형식의 별도 엔터티에서 통합 관리하는 방법
- 이력 데이터를 종 테이블 형식으로 설계하는 모델
- 계좌속성 엔터티는 계좌 엔터티의 속성중에서 이력 데이터를 관리할 속성을 관리하는 기준 엔터티
- 계좌이력 엔터티는 계좌에 대한 속성을 기준으로 변경된 속성 값을 관리하는 엔터티
- 계좌속성 엔터티에 대한 부가적인 부담이 발생
- 계좌이력 엔터티에서 관리할 속성이 명확하진 않다
- 계좌관리사원번호 속성을 별도의 엔터티에서 변경 데이터를 관리하는 모델
- 별도로 이력 데이터를 관리하는 엔터티와 혼용해서 사용하면 실제로 어떤 속성을 계좌이력 엔터티에서 관리하는지 불명확하다
- 특정 시점의 모든 속성 데이터를 조회하기 어렵다
- 모델을 형상관리할 필요가 없어 유연한 구조의 모델이다
- 변경된 별도의 속성을 조회하기는 유리
- 데이터 저장 공간이 절약된다
- 설계하기 쉽다
6.12 이력 데이터를 종 테이블로 설계하는 다양한 방법
- 종 테이블 설계를 하나의 엔터티에서 두 개 이상의 엔터티로 확장한 모델
- 통합이력 엔터티는 계좌,고객 엔터티 등의 변경 데이터를 통합 관리하는 엔터티
- 고객계좌통합번호 속성은 배타 관계를 관리하는 속성 (이력엔터티번호 속성과 함께 사용해야 어떤 엔터티의 식별번호인지 알 수 있다 )
- 최대한 유연한 설계 방법
- 엔터티 갯수가 많이 줄어든다
- 이력 관리 대상 엔터티의 주 식별자가 배타 관계를 만들기 때문에 주의해야 한다
- 수퍼,서브타입 모델의 이력 데이터를 설계 (배타속성의 단순성)
- 통합이력 엔터티에서 고객, 개인고객, 법인고객의 이력 데이터를 관리하는 모델
- 이력 데이터를 종 테이블로 설계
- 변경 행위를 기준으로 변경된 속성을 관리하는 모델(같이 변경된 속성을 알 수 있다)
- 계좌 엔터티의 데이터가 변경될 때마다 계좌변경이력에 데이터가 생성되며, 변경된 속성에 대해서는 계좌변경이력속성 엔터티에서 관리
6.13 함께 변경된 속성을 알아야 할 때
- 이력 엔터티를 종 테이블로 설계하면서 변경된 속성을 알아야 할 요건이 있는 모델
- 계좌이력 엔터티의 변경순번 속성 값이 같으면 동시에 변경된 속성 ( 변경순번 주식별자 수정 )
- 변경순번은 같이 변경된 속성을 알기 위해 업무적으로 필요한 속성, 부분 인조 식별자와는 다르다
6.14 선분이력
- 과거 특정 시점의 데이터를 조회하는 요건이 많을 때 사용하는 방법으로 조회 성능을 고려한 기법
- 선분이력은 데이터가 유효한 시작 시점과 종료 시점을 관리하는 방법
- 점(시점)이력 릴레이션
- 쿼리가 복잡해지고, 성능 측면에서 비효율이 발생
- 선분이력 릴레이션
- 현재 데이터는 종료 시점이 없어서 9999년12월31일과 같이 약속된 데이터를 사용
- 논리적으로 종료일자는 널(Null)값을 입력해야 하지만 성능을 위해 기본값을 사용
- 선분이력은 변경된 릴레이션의 시작과 종료 시점을 연결하면 하나의 선분이 되는 것이 중요
- 시작일자와 종료일자가 겹치지 않도록 해야한다 (?)
- Between 구문을 사용해 조회 쿼리의 효율성을 높일 수 있다
- 점이력은 변경일자만 관리하므로 선분이 되지 않는다
- 선분의 개념을 이용한 극장 좌석 예약 상태를 관리하는 릴레이션
- 예약이 안 된 연속된 좌석을 알아야 하는 요건
6.15 선분이력의 종료일자
- 선분이력의 핵심이 종료일자에 대한 설명
- 선분이력은 심각한 성능문제가 있는 경우에만 사용(남용 방지)
- 성능문제가 없다면 변경일자를 사용해야 한다
- 계좌 엔터티에는 현재 유효한 관리사원 데이터를 관리하고, 계좌관리사원이력 엔터티에는 변경 데이터를 관리한다
- 선분이력 사용시 종료일자를 주 식별자에 포함시키는 것이 효과적
- 종료일자는 추출 속성
- 데이터 무결성이 깨질 수 있다
- 시작일자와 종료일자를 연결해 선분이 되지 않는 예
- 계좌관리사원번호를 점이력으로 관리하는 모델
- 계좌관리사원번호를 선분이력으로 관리하는 모델
- 유효한 관리사원은 유효종료일자가 '9999-12-31'인 인스턴스
- 선분이 될 수 있도록 종료일자 데이터를 로직으로 계산
- 이 릴레이션의 문제는 주식별자인 유효종료일자 속성 값을 업데이트한다는 것
- 유효종료일자 속성의 추가로 저장 용량 증가
6.16 기간을 의미하는 종료일자
- 기간을 의미하는 종료일자 속성은 이력 데이터와 다르므로 구별해야 한다
- 보험시작일자, 보험종료일자는 추출속성이 아니고, 보험기간을 의미하는 업무에서 사용하는 속성
- 그림6.102 : 보험계약을 선분이력 방법으로 설계한 모델
- 그림6.102
- 보험계약 당시 릴레이션 (2035년4월30일 계약기간 10년) - 보험시작일자 : 2035-05-01 수정
- 그림6.103
- 2045년3월2일 계약기간을 2050년4월30일까지로 연장 - 보험종료일자 : 2045-04-30 수정
- 2045년3월10일 계약기간을 2055년4월30일까지로 연장한 릴레이션
- 유효시작일자, 유효종료일자는 선분이력 관리 속성으로 연결하면 선분이 되지만 보험시작일자와 보험종료일자는 계약기간을 나타내므로 선분이 되지 않는다
6.17 이력 엔터티의 주 식별자
- 선분이력 엔터티에 종료일자 속성이 주 식별자에 포함돼야 하는지와 인조 식별자인 변경순번 속성을 사용해야 하는지를 설명
- 계좌의 비밀번호를 관리하는 일반적인 이력 모델
- 시작일자와 종료일자 속성 중에 어떤 속성이 주 식별자에 포함돼야 하는지는 성능관점에서 판단
- 유효시작일자가 주 식별자에 포함된 모델
- 필요한 인덱스
- Primary Key : 계좌번호 + 유효시작일자
- Index1 : 계좌번호 + 유효종료일자
- Unuque Index : 계좌번호 + 유효시작일자 + 유효종료일자
- 과거 특정일(변경된)을 조회하기 위해 필요한 인덱스
- 유효종료일자가 주 식별자에 포함된 모델
- 주 식별자에 업데이트가 발생
- 현재 유효한 비밀번호를 조회할 때 PK 인덱스를 사용할 수 있다
- 필요한 인덱스
- Primary Key : 계좌번호 + 유효종료일자
- Unuque Index : 계좌번호 + 유효시작일자 + 유효종료일자
- 과거 특정일(변경된)을 조회하기 위해 필요한 인덱스
- 변경순번을 주 식별자에 포함시킨 모델
- 변경순번 같은 부분 인조 식별자를 사용하는것은 지양
- 하위 엔터티가 존재하며, 현재 유효한 데이터와만 관계를 가질 때 하위 엔터티에 미치는 영향을 줄이기 위해 사용
- 하루에도 여러 번 변경될 수 있는 요건 때문이라면 변경일시를 사용
- 선분이력 엔터티면서 주 식별자에 변경순번 속성을 간혹 사용
- 필요한 인덱스
- Primary Key : 계좌번호 + 변경순번
- Index1 : 계좌번호 + 유효종료일자
- Unuque Index : 계좌번호 + 유효시작일자 + 유효종료일자
- 가장 비효율적인 선분이력 모델
- 하위 엔터티가 존재할 때, 하위 엔터티에 미치는 영향을 줄이기 위한 모델
- 하위 엔터티와 참조 무결성 제약이 존재하지 않는 것이 좋다
- 새로운 인스턴스는 변경순번을 '1'로 인서트하고, 기존 인스턴스의 변경순번은 +1씩 업데이트한다
- 하위 엔터티가 존재하는 점이력 모델인 경우
- 하위 엔터티의 변경을 해소할 수 있다
6.18 이력 엔터티 설계 절차
- 이력 엔터티를 설계하는 시작점은 이력 데이터를 관리하는 요건이 있느냐다
- 이력 관리 요건분석 : 원천 데이터를 변경할 때 변경된 데이터를 저장해야 하는지를 분석
- 이력관리유형 선택 : 본질 엔터티를 정확히 설계한 후 다섯가지 중 하나를 선택
- 선분이력요건 : 성능을 고려
- 이력엔터티 주식별자 : 다른 엔터티와의 관계까지 감안해서 결정
6.19 서브타입의 이력 모델
- 슈퍼타입,서브타입 모델에 대하여 이력 엔터티를 설계하는 방법
- 그림6.115 : 676 페이지 참조
- 고객이력 엔터티는 조회하지 않고 개인고객이력 엔터티만 조회하는 경우 유리
- 서브 타입별로 이력 데이터를 관리
- 개인고객 데이터가 변경되면 개인고객이력 엔터티에만 데이터가 생성되고 고객이력 엔터티에는 생성하지 않음
- 고객 데이터에 대하여 변경된 내역을 조회한다면 고객이력 엔터티와 개인고객이력 엔터티에서 데이터를 추출해야 하는 어려움이 있다
- 개인고객이력 엔터티의 속성값이 변경될 때 고객이력 엔터티에도 데이터를 생성
- 고객이력엔터티와 개인고객엔터티가 개별적으로 관리하도록 한 설계 의도와 맞지 않음
- 이력 엔터티간 데이터 무결성 문제 발생
- 엔터티 단위의 이력 관리
*[그림6.118] : 679 페이지 참조
- 서브타입간의 참조 무결성 제약이 존재하므로 서브타입 모델을 이력관리할 때도 참조 무결성이 제약이 존재하는 모델이 타당
- 참조 무결성 향상
- 조회가 용이
- 특정 시점의 고객 전체 데이터를 조회하려는 요건이 있을 때 유리
- 성능 문제가 있으면 선분이력 방법을 적용할 수 있다
- 엔터티 단위의 이력 관리
그림6.119 : 680 페이지 참조
6.20 정정 데이터
- 정정 데이터는 이미 존재하는 데이터가 잘못돼 수정한 데이터
1. 정정에 대한 이력 관리 안함
- 기존 데이터를 정정해야 하는 데이터로 업데이트 발생
- 세번째 인스턴스의 계좌비밀번호를 1000 -> 1001로 업데이트
2. 정정하기 이전 데이터를 단순히 참고용으로 관리하는 모델
- 정정계좌비밀번호 엔터티에서는 정정된 데이터만 관리
3. 하나의 엔터티에서 변경이력과 정정 데이터를 함께 관리
- 변경정정구분코드는 변경인지 정정인지를 구분하는 속성
- 정정대상인 세 번째 인스턴스는 변경정정구분코드 값만 변경에서 정정으로 업데이트한다
- 새롭게 생성될 인스턴스의 변경정정구분코드 속성값은 '변경'으로, 계좌비밀번호는 정정 이후의 올바른 값 '1000'으로 생성
- 이력 데이터와 정정 데이터를 같이 조회해야하는 요건이 빈번할때 효율적인 모델
- 정정 데이터는 간혹 사용되며 이력 데이터가 자주 사용된다면 정정과이력 엔터티를 분리하는게 바람직한다