이력 데이터 관리 방법 (세가지 분류)

엔터티의 속성 중에서 하나라도 변경되면 변경 전의 전체 인스턴스를 그대로 관리
  • 저장 공간의 낭비
  • 저장이 쉽고 해당 시점의 전체 데이터 조회도 쉽다 (스냅샷)
  • 변경된 속성의 데이터만을 조회하기 어렵고 조회 처리가 복잡해짐


변경된 속성만을 개별적으로 관리
  • 저장 공간의 절약
  • 변경된 속성이 무엇인지 명확함
  • 속성 별로 하나의 엔터티에서 별도 관리시 이력 관리가 필요한 속성 도출이 어려움
  • 속성 전체를 하나의 엔터티에서 관리시 변경 데이터 저장은 쉬우나, 조회가 어렵고 필요한 속성만이 포함되도록 관리 하기가 어려움
  • 이력 데이터를 관리해야 하는 속성이 광범위 하고 가변적 이라면 하나의 엔터티에서 전체 속성의 이력 데이터를 관리하는 방법이 유용할 수 있음 (이 때도 자주 변경되고 조회도 빈번한 속성은 별도의 엔터티에서 개별적으로 관리하는 것이 좋음)


유사한 속성을 묶어서 관리
  • 속성 중 내용(도메인)이 유사하거나 같이 사용될 수 있는 속성만으로 별도의 엔터티를 만들고, 해당 속성중 하나라도 변경되면 그 시점의 데이터 인스턴스를 스냅샷으로 관리
  • 인스턴스로 관리하는 방법과 개별 속성으로 관리하는 방법의 장점을 수용한 방식 (잘못 사용되면 단점만을 수용할 수도 있음)
  • 유사한 성격의 이력 데이터가 하나의 엔터티에서 관리되므로 엔터티의 성격이 분명해지는 장점 (효율적)
  • 해당 시점의 전체 인스턴스 조회시 머지(Merge) 발생으로 처리가 어려움


※ 이력 데이터 관리 방법을 하나로 획일화 하는것은 옳지 않음
※ 엔터티의 성격과 요건, 중요도에 맞춰 다양한 방법이 사용되어야 함
※ 요건에 가장 합당한 방법을 채택할 수 있는 힘 필요


① 엔터티 하나로 현재와 과거 데이터 관리

  • 하나의 엔티티에서 과거, 현재, 미래 데이터를 함께 관리
  • 속성 중 하나라도 변경되면 변경된 데이터로 업데이트 하고, 변경 전 과거 데이터는 새로운 인스턴스로 생성
  • 과거 데이터 사용 빈도가 높을때 효과적 이며 현재 데이터만 사용 한다면 엔터티를 분리 하는것이 효율적
  • 데이터 모델 관리, 개발(하나의 프로그램), 데이터 생성이 편리함
하나의 엔터티두 개의 엔터티
하위 엔터티를 가질 수 없음 (확장성X)속성 추가시 두 엔터티 및 두개 프로그램 수정 필요
  • 장/단점이 명확하지 않다면 모델의 변경 관리를 위해 하나의 엔터티 고려 가능
하위 엔터티가 존재할 수 없는 모델 (나쁜사례)
가정 : 주문 내용의 변경된 데이터를 주문 엔터티에서 관리 하고, 변경은 하루에 한번만 가능


변경전 릴레이션
  • 주문
#주문번호#변경일자#배송처
1002019-05-05서울시
  • 주문상품
#주문번호#변경일자#상품코드주문수량
1002019-05-0510101
1002019-05-0510203
1002019-05-0510502


변경후 릴레이션1 (하위 엔터티와 관계가 끊어진 릴레이션)
  • 주문 다음날 100번 주문의 배송처가 집에서 사무실로 변경
  • 주문상품 릴레이션에 변경일자가 2019-05-06 인 데이터가 없기 때문에 주문 상품이 무엇인지 쉽게 알기 어려움 (주문 엔터티에서 변경 직전 인스턴스 추적 필요)
  • 주문
#주문번호#변경일자#배송처
1002019-05-05서울시
1002019-05-06경기도
  • 주문상품
#주문번호#변경일자#상품코드주문수량
1002019-05-0510101
1002019-05-0510203
1002019-05-0510502


변경후 릴레이션2 (하위 엔터티의 이력을 관리하는 릴레이션)
  • 주문상품 (변경일자 업데이트 / 실전선택)
#주문번호#변경일자#상품코드주문수량
1002019-05-0610101
1002019-05-0610203
1002019-05-0610502
  • 주문상품 (새로운 변경일자로 인스턴스 생성 / 필자선택)
#주문번호#변경일자#상품코드주문수량
1002019-05-0510101
1002019-05-0510203
1002019-05-0510502
1002019-05-0610101
1002019-05-0610203
1002019-05-0610502

※ 두개 모두 바람직 하지 않음, 하위 엔터티(주문상품)를 쫒아다니면서 해당 인스턴스를 변경/추가 하는것은 한계가 있음
※ 하위 엔터티가 존재할 때는 하나의 엔터티에서 변경 데이터를 같이 관리하면 안됨

보통 데이터 조작은 한번 이지만, 조회는 수없이 일어나므로 조회에 최적화 하는것은 의미가 있음


좋은사례
주문 이력 엔터티 (좋은사례)
릴레이션
  • 100번 주문의 배송처가 2019-05-06 에 '경기도' 로 변경 된 후 2019-05-07 에 '대전시' 로 변경됨
  • 변경 발생시 하위 엔터티의 데이터는 아무 변함이 없어야 함 (그렇지 않은 경우는 극단 적인 경우를 제외하고 발생 해서는 안되며 모델이 잘못된것)
  • 주문
#주문번호#변경일자#배송처
1002019-05-07대전시
1012019-05-08서울시
  • 주문이력
#주문번호#변경일자#배송처
1002019-05-05서울시
1002019-05-06경기도
  • 주문상품
#주문번호#상품코드주문수량
10010101
10010203
10010502
10110102

엔터티 하나로 현재와 과거 데이터 관리

  • 인스턴스 단위로 변경 관리하므로 변경된 속성만을 찾을 수가 없음
  • 해당 인스턴스의 전체 속성을 조회할 때는 적합
  • 시점 데이터를 스냅샷 형태로 보관 하므로 공간을 많이 차지함
  • 데이터 조회가 하나의 엔터티에 집중됨
  • 핵심 실체/행위 엔터티는 하나의 엔터티에서 현재와 과거의 데이터를 관리하면 대개 바람직 하지 않음


모델
현재+과거 엔터티
  • 수수료율 엔터티는 하위 엔터티가 발생하지 않는다. (기준 정보 엔터티)
  • 이런 종류의 기준 엔터티는 대부분 하위 엔터티와 참조 무결성 관계가 성립하지 않는다.
    • 실제로 참조 무결성 관계가 있는지, 참조 무결성 관계로 관리 하는것이 실익이 있는지 고려 필요
    • 과거 특정 시점 값을 조회하는 요건이 있을 때 하나의 엔터티에서 관리 하는것이 단순해짐 (하나의 프로그램, 하나의 SQL)
    • 하나의 엔터티에서 과거와 현재 데이터를 관리할 때는 엔터티명에 "~이력"을 사용하지 않는 것이 일반적


모델
현재와 과거 데이터를 별도로 관리하는 모델
  • 유효시작일자, 유효종료일자는 선분 이력으로 관리 하기 위해 사용하는 속성
  • 과거 특정 시점의 조회가 빈번하고 최적 성능을 요할때 채택
  • 하위 엔터티가 존재하지 않고, 과거 특정 시점의 수수료율이 빈번하게 조회되므로 굳이 두개 엔터티로 나눌 필요는 없음


모델
선분 이력이 아닌 엔터티
  • 성능상의 이슈가 없다면 변경일자를 관리 하는것 으로 충분 (점 이력)
  • 최근의 데이터를 효율적으로 관리하기 위해 사용여부 추출 속성 고려 가능

하루에 두번 이상 변경될 때

변경일자, 시작일자, 종료일자는 연/월/일 만 관리 하므로 데이터가 하루에 한번만 변경 가능, 하루에 두번 이상 변경 될 수 있다면 변경일시, 시작일시, 종료일시 사용


모델
변경순번 속성을 사용한 이력 엔터티
  • 데이터가 하루에 여러번 변경될 수 있을 때 실무에서 변경순번 속성을 사용하나 주 식별자에 순번 속성을 사용해 업무 식별자를 숨기는 것은 가능한 피해야 함
    • 변경순번은 계좌상품코드, 거래채널코드에 따른 순차적인 번호, 실무에서 무작위로 순번을 사용하는 경우가 빈번(X)
    • 변경순번을 사용하면 주 식별자에 업무 식별자 성격과 인조 식별자 성격이 섞이게 되어 업무 식별자가 모호해짐
    • 변경순번 위에 존재하는 주 식별자 속성을 임의대로 정해도 식별이 되므로 기준이 없게 됨 (계좌상품코드 + 변경순번 ==> 식별가능)
    • 가능한 계좌상품코드 + 거래채널코드 + 변경일자 속성을 주 식별자로 사용 하는 것이 바람직


② 두 개의 엔터티에서 현재와 과거 데이터 별도로 관리

  • 변경 되는 속성이 하나라도 발생하면 그 시점의 스냅샷 데이터를 과거 데이터를 관리하는 엔터티로 복사 후 현재 데이터를 관리하는 엔터티 변경
  • 핵심 엔터티에는 하나의 엔터티에서 과거와 현재의 데이터를 모두 관리하지 않는다.
    • 하위 엔터터 존재 문제, 데이터 건수가 많아지는 문제


모델
스냅샷 방식의 이력 관리 모델
두 개의 엔터티에서 현재와 과거 데이터를 분리해 관리하는 기본 모델, 현재[보험계약] / 과거[보험계약이력]
  • 보험계약이력 엔터티는 과거의 데이터를 관리 하기 때문에 엔터티 이름에 "~이력" 을 사용 함
  • 보험계약이력 엔터티는 보험계약 엔터티의 주 식별자를 식별 관계로 상속 받고, 시작일자,종료일자/변경일자 속성을 추가 한다.
  • 보험계약 엔터티 속성 중 하나라도 변경되면 변경 전 데이터를 스냅샷 형태로 보험계약이력 엔터티에 입력하고 (종료일자는 로직에 의해 계산), 보험계약 엔터티에 변경 후 데이터를 반영 한다.
  • 변경된 속성이 무엇인지 알기 어려움
  • 보험계약 엔터티에 하위 엔터티가 존재할 수 있음 (하위 엔터티가 많은 핵심 실체/행위 엔터티에 적용 가능)


릴레이션 (현재 데이터와 과거 데이터 각각 관리)
  • 2020-10-10 '12345' 증권의 상품이 'A00' 에서 'A10' 으로 변경되고, 보험가입금액이 '1000'원 에서 '1200'원으로 변경됨
  • 보험계약
#증권번호상품코드보험가입일자보험가입금액
12345A102020-01-011200
23456B202020-05-04500
  • 보험계약이력
#증권번호#유효시작일자유효종료일자상품코드보험가입일자보험가입금액
123452020-01-012020-10-09A002020-01-011000


릴레이션 (보험계약이력 엔터티에서 현재 데이터도 관리)
  • 현재/과거 데이터를 동시에 조회하는 요건의 중요도(성능과 사용빈도)에 따라 적용할 수 있지만 데이터 중복이 심하게 발생하므로 지양
  • 보험계약
#증권번호상품코드보험가입일자보험가입금액
12345A102020-01-011200
23456B202020-05-04500
  • 보험계약이력
#증권번호#유효시작일자유효종료일자상품코드보험가입일자보험가입금액
123452020-10-109999-12-31A102020-01-011200
123452020-01-012020-10-09A002020-01-011000
234562020-05-049999-12-31B202020-05-04500
  • 하위 엔터티가 존재하지 않는다면 하나의 엔터티에서 관리하는 방법이 나을 수 있음 (필자)
    • 두 개의 엔터티는 모델 형상 관리가 복잡함 (이중 관리)
    • 두 개의 엔터티는 유연성이 좋음 (현재는 하위 엔터티가 없지만 미래에 생길 경우를 대비)
  • 미래까지 고려한 하위 엔터티 존재 여부와, 과거 데이터의 조회 빈도에 따라 하나의 엔터티로 관리할지 두 개로 관리할지 판단


서브타입 모델의 이력 관리 방법
예제1슈퍼타입과 서브타입을 합친 인스턴스별로 이력데이터 관리(서브타입 개념 반영, 연결된 인스턴스 조회 편리)
예제2슈퍼타입과 서브타입별 각각의 이력 데이터 관리(이력 데이터 발생 쉽고, 공간 절약)


③ 변경 속성을 별도의 엔터티로 관리

변경되는 속성만을 관리
계좌비밀번호 속성의 이력 엔터티
  • 계좌비밀번호이력 엔터티에서는 과거의 비밀번호만을 관리하고(~이력), 현재의 비밀번호는 계좌 엔터티에 존재
  • 데이터 값 중복 없음, 데이터 모델의 속성 중복 있으므로 상대적으로 좋지 않지만 업무적으로 현재 비밀번호가 주로 조회 되므로 적정


변경되는 속성만을 관리
계좌비밀번호 변경 내역 엔터티
  • 계좌 엔터티에는 계좌비밀번호 속성이 없음
    • 효율을 위해 계좌비밀번호 속성을 추가해 현재 비밀번호를 중복 관리 고려 가능
  • 현재/과거 비밀번호를 하나의 엔터티에서 관리
    • 계좌비밀번호 엔터티는 계속 발생 하는 내역 엔터티, ~이력 X
    • 과거 특정 시점의 비밀번호를 조회하는 요건이 중요 하다면 변경일자 대신 시작일자+종료일자 속성 적용 가능


모델
여러 유형의 계좌비밀번호 발생 내역
  • 계좌별로 여러개의 비밀번호가 존재하는 경우 (계좌비밀번호.비밀번호구분코드)
  • 현재/과거 비밀번호 : 계좌비밀번호 엔터티


모델
여러 유형의 계좌비밀번호의 발생 내역과 변경 이력
  • 현재 비밀번호 : 계좌비밀번호 엔터티
  • 과거 비밀번호 : 계좌비밀번호이력 엔터티


모델
관계(역할) 이력 관리 모델
  • 계좌관리사원 엔터티에서 계좌를 현재 관리하고 있는 사원과, 과거에 관리했던 사원 데이터를 함께 관리
    • (~이력 X)
    • 과거 관리 사원 조회 빈도를 고려해 선분 이력 구현 (시작일자+종료일자)
    • 현재 계좌 관리 사원을 알려면 항상 계좌관리사원 엔터티와 JOIN 필요
    • 계좌를 가장 많이 관리하고 있는 '홍길동' 사원의 전체 계좌 정보 조회, 지점별 관리자가 관리하는 계좌 숫자와 예수금 총액 화면등에서 성능 문제 발생 가능


모델
추출 속성을 사용한 관계(역할) 이력 관리 모델
  • 현재 계좌관리사원 관련 성능문제를 고려해 계좌 엔터티에 추출 속성 (현재계좌관리사원번호) 적용
  • 대부분 요건은 계좌 엔터티 로 처리 하고, 과거 특정 시점 관리 사원 정보 필요시 계좌 + 계좌관리사원 엔터티로 처리
    • 계좌, 계좌관리사원 엔터티에 중복된 현재 관리 사원 데이터중 계좌관리사원 엔터티 쪽이 원천 데이터이며, 계좌 쪽은 추출된 중복 데이터임
  • 데이터 무결성이 최우선 요소지만 무조건 항상 그런 것은 아니며, 성능을 우선으로 고려해야 하는 경우가 존재


모델
현재와 과거 관리사원을 별도로 관리하는 모델
  • 계좌 엔터티에서는 현재 관리 사원만 관리하고, 과거 관리 사원은 계좌관리사원이력 엔터티에서 관리
    • 계좌관리사원이력 : ~이력 O
    • 계좌.계좌관리사원번호 : 현재~ X
    • 현재,최근,최초 등의 단어가 사용되면 일반적으로 추출 속성


모델
여러 역할을 관리하는 모델
  • 계좌를 관리하는 사원, 계좌를 유치한 사원과 같이 다양한 역할을 계좌관계사원 엔터티와 같이 통합해 관리
    • 계좌관계사원.계좌관계사원구분코드 : 관리사원, 유치사원, 운용사원, 실적사원...
    • 여러 역할을 통합 관리하므로 엔터티명, 속성명에 좀더 일반적인 용어 적용 (관리 -> 관계)


모델
여러 역할을 관리하는 모델에 추출 속성을 적용한 모델
  • 속성 단위로 변경 데이터를 관리하는 이력 방법은 속성의 명확한 정의가 선행 되어야 함
    • 장점 : 엔터티의 성격이 분명해지고 모델을 보고 업무파악이 더욱 쉬워지고, 커뮤니케이션에 많은 도움이 됨
    • 단점 : 속성별 이력 요건 분석이 필요하므로 모델링 기간이 늘어나고, 모델링이 힘들어짐, 인스턴스별로 조회하기 어려움
  • 별도의 엔터티에서 하나의 속성 값이 변하는 데이터를 관리한다는 것은 해당 데이터가 그만큼 중요하다는 의미
    • 엔터티가 증가하게 되므로 꼭 필요하다고 판단될 때만 적용


  • 정규화는 엔터티 개수가 아무리 늘어나더라도 데이터 성격을 명확하게 정의하고 무결성 확보를 위해 반드시 필요


④ 모든 변경 속성을 하나의 통합 엔터티로 관리

변경된 모든 속성의 데이터를 하나의 엔터티에서 관리
  • 이력 관리 대상 속성을 코드화해서 관리
  • 코드화 엔터티에 대한 관리 부담 발생 (이력 발생전 기초 데이터 등록, 속성이름 정합성 유지)
  • 이력 엔터티에서 관리할 속성이 보통 명확하지 않은 문제점이 있음
    • 속성별로 상세한 업무 파악이 필요하지 않아 엔터티의 성격이 모호해짐
    • 모델만 봐서는 이력에 대한 업무를 상세하게 파악하기 어려우며 모델의 가독성이 낮음
  • 인스턴스의 스냅샷 저장이 아니므로, 특정 시점의 모든 속성 데이터를 조회하기가 어려움 (개별 속성 조회는 쉬움)


유일한장점 : 모델 형상 관리 불필요 (유연성)
  • 다른 엔터티의 변경 이력도 통합해 관리 가능 (유연성↑ / 가독성↓)


릴레이션
  • 계좌 번호가 '12345678'인 계좌의 관리 사원이 2021-07-07에 '홍길동' 에서 '김길동' 으로 변경된 후, 2021-12-31 다시 '박길동'으로 변경됨
  • 계좌이력속성
#속성코드속성명
100계좌명
110계좌관리사원번호
120계좌비밀번호
  • 계좌이력
#계좌번호#속성코드#시작일자종료일자속성값
123456781102021-05-052021-07-06홍길동
123456781102021-07-072021-12-30김길동


모델
변경 속성을 코드로 관리하는 모델
  • 계좌이력속성 엔터티 : 계좌의 속성을 코드로 관리하는 엔터티
  • 계좌 속성 중에 변경되는 속성이 생기면 계좌이력속성 엔터티에 속성코드와 속성명으로 데이터 생성 필요
    • 계좌이력속성.속성명 의 값은 계좌 엔터티의 속성 이름과 일치시켜야 함


모델
이전 속성 값을 관리하는 모델
    • 변경 이전에 어떤 값이었는지를 알아야 할 때 '이전속성값' 추출 속성 적용


  • 여러 단점에도 불구하고 사용하기 편하다는 장점으로 실무에서 자주 사용됨
  • 이 유형의 모델 채택은 업무를 분석하기 어렵거나, 분석할 의사가 별로 없다는 의미로 인식 (필자는 마음이 편치 않음)


모델
동시에 변경된 속성을 관리하는 모델
  • 동일한 업데이트 트랜잭션에 의해 변경된 속성이 무엇인지 알 수 있음
    • 변경순번 속성 값이 같으면 동시에 변경된 속성
    • 일반적으로 ~순번 속성은 인스턴스 유일성을 보장하기 위한 인조 식별자로 사용되는데, 이 모델에서는 같이 변경된 속성을 구분하기 위한 업무 식별자 성격임


릴레이션
  • 가장 최근에 함께 변경된 속성은 계좌관리사원('123') 과 계좌비밀번호('2222') 임
  • 계좌 데이터는 세번에 걸쳐 변경됐고, 변경된 속성은 네개 이며, 계좌 비밀번호는 두 번 변경 됨
  • 계좌이력속성
#속성코드속성명
100계좌명
110계좌관리사원번호
120계좌비밀번호
  • 계좌이력
#계좌번호#변경순번#속성코드변경일자속성값
1234567831102021-07-07123
1234567831202021-07-072222
1234567821002021-05-05홍길동
1234567811202021-02-101111
  • 어떤 속성의 변경 데이터를 이력 관리해야 하는지에 대한 기본적인 요건이 확정되지 않았다면 이력 관리 모델을 유보 하는것이 옳음
    • 요건이 확정되지 않았다고 일반적이고 유연한 모델을 선택하는 것은 안됨


⑤ 유사한 변경 속성들을 묶어서 별도의 엔터티로 관리

  • 여러 개의 속성이 하나의 엔터티에서 관리된다는 점을 제외하고 변경된 속성만을 별도의 엔터티에서 관리하는 방법과 유사
  • 엔터티의 정체성과 모델의 확장성, 유사 속성의 조회 편이성이 좋아지고, 엔터티도 많이 늘지 않음
유사한 속성을 묶어서 이력 관리하는 모델
  • 보험계약일자이력 엔터티에서는 보험과 관련된 날짜의 변경 이력을 관리 하고, 보험계약금액이력 엔터티에서는 금액 관련 속성을 이력 관리 한다.
    • 보험종료일자 속성 값이 변경되면 보험계약일자이력 엔터티에만 한 인스턴스가 생성됨 (특정 시점의 하나의 인스턴스 전체를 조회하기 쉽지 않음)
    • 유사한 관리 속성으로 말미암아 비교적 데이터 성격이 분명한 엔터티가 생김 (업무 파악 용이성)
    • 엔터티를 인스턴스 단위로 이력 관리하는 방법과 속성 단위로 이력 관리하는 방법의 장점을 취할 수 있음 (양쪽의 단점만을 취하지 않도록 주의)
  • 요건에 따라 가장 효율적일 수 있지만, 자주 발생할 수 있는 모델은 아님


다섯가지 이력 관리 유형의 장/단점

구분인스턴스(스냅샷)/하나의 엔터티인스턴스(스냅샷)/두 개의 엔터티속성(개별)/이력 속성 엔터티속성(개별)/코드성 엔터티속성그룹
이력 데이터 발생 용이성GoodGoodGoodBadNormal
변경 속성 조회 용이성BadBadGoodGoodBad
이력 모델 형상 관리GoodBadGoodGoodNormal
하위 엔터티 확장성BadGoodGoodGoodGood
전체 데이터(스냅샷) 조회GoodGoodBadBadNormal
모델의 유연성(확장성)BadNormalGoodGoodNormal
데이터 중복성BadBadGoodGoodNormal
데이터 중복성BadBadGoodGoodNormal
엔터티 성격 명확성BadBadGoodBadNormal
데이터 저장 공간 효율성BadBadGoodGoodNormal