태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

드디어 마지막 열 번째 방법입니다.

 

- 마스터에 해당 속성이 존재해 현재 데이터를 관리하고, 속성 그룹의 이력 데이터는 별도의 엔터티에서 관리

- 마스터에 해당 속성이 존재하지 않고, 속성 그룹을 별도 하나의 엔터티를 사용해 현재+과거 데이터를 통합해서 관리

- 마스터에 해당 속성이 존재하지 않고, 속성 그룹을 두 개의 엔터티를 사용해 현재와 과거 데이터를 개별로 관리

 

유사한 속성을 묶어서 별도의 엔터티로 설계하며, 현재 데이터와 변경된 과거 데이터를 따로 관리합니다.

 

앞서 밝혔듯이 구분하는 게 도움이 되기 때문에 구별했지만 다섯 번째 방법과 유사합니다.

 

이력 엔터티를 설계하는 다섯 번째 방법



[그림1]

 

주식종목가격 엔터티의 속성 값이 하나라도 바뀌면 주식종목가격이력 엔터티에 데이터가 생성합니다.

 

기준가가 바뀌면(16000에서 17000으로) 주식종목가격 엔터티에는 기준가 속성만 17000으로 업데이트되고, 주식종목가격이력 엔터티에는 변경 전 스냅샷 인스턴스로 인서트됩니다.

 

물론 [그림2] 상단 릴레이션처럼 스냅샷으로 등록하지 않고, 하단 릴레이션처럼 변경된 데이터만 생성하는 방법도 있습니다.

 

[주식종목가격이력]

#주식종목번호

#변경일자

액면가

기준가

1000

2026-01-15

5000

16000

 

[주식종목가격이력]

#주식종목번호

#변경일자

액면가

기준가

1000

2026-01-15

{null}

16000

 

[그림2]

 

하지만 유사한 여러 속성을 묶어서 하나의 엔터티에서 관리하는 주요 이유는 속성이 같이 사용되기 때문인데 하단 릴레이션은 이 점에서 문제가 있어 보입니다.

 

변경 값만 알려면 [그림2] 하단 릴레이션처럼이 아니라 여섯 번째 방법처럼 종테이블(Vertical Table)로 관리하는 것이 바람직합니다.

 

이력 엔터티를 설계하는 여섯 번째 방법


변경된 속성과 변경되지 않은 속성이 같이 조회될 가능성이 조금이라도 있다면 스냅샷 방식으로 관리하는 것이 좋습니다
.

 

이 마지막 방법은 이전 방법에 비해 엔터티의 개수가 늘었지만 자주 사용하는 현재 데이터만 별도 엔터티에 존재하므로 현재 데이터를 조회하기 수월합니다.

 

속성 그룹이라는 거 빼고는 다섯 번째 방법과 특징이 동일합니다.

 

이상으로 이력 데이터를 설계하는 10가지 방법에 대해 설명드렸습니다. 예상보다 오래 걸렸네요.

 

이 중에서 2가지(네 번째, 아홉 번째 방법)는 발생 내역 데이터이지만, 이력 엔터티를 설계할 때 도움이 되므로 포함시켰습니다.

 

이력 데이터는 본질 데이터로부터 영향을 받습니다.

본질 엔터티를 분명히 한 후에 이력 데이터를 설계해야 합니다.

 

또한 이력 엔터티는 엔터티 정의와 밀접하게 연관돼 있습니다.

엔터티 정의를 어떻게 하느냐에 따라 이력 엔터티도 영향을 받습니다.

 

이력 엔터티를 올바르게 정의하려면 원천 엔터티가 올바르게 정의돼야 하므로, 즉 원천과 이력 엔터티를 올바르게 정의해야 하므로 이력 엔터티를 제대로 설계하긴 쉽지 않습니다.

 

1~2가지 방법으로는 다양한 요건을 만족할 수 없습니다. 모든 이력 엔터티를 스냅샷 방식의 선분이력으로 설계한다는 식의 생각은 지양해야 하고요.

 

이번 시리즈에서 설명한 10가지의 다양한 설계 방법으로 다양한 요건을 대응할 수 있길 바랍니다.

 


블로그 이미지

블루퍼필

댓글을 달아 주세요

  • 정유성 2012.01.02 15:16  댓글주소  수정/삭제  댓글쓰기

    이력 엔터티를 설계하는 방법을 유형별로 아주 자세히 설명해 주신 것 같습니다. 감사드립니다.

    • 블루퍼필 2012.01.03 11:24 신고  댓글주소  수정/삭제

      감사합니다.

      아직도 이력 관리는 만족 못하고 있지만 최대한 체계적으로 정리하려 노력했습니다.
      많은 사람들이 읽어봤으면 하는 내용이기도 하고요. ㅎ

      복된 한 해 되세요.

아홉 번째 방법은 유사한 속성을 묶어서 별도의 엔터티로 설계하고, 이력 데이터도 같이 관리하는 겁니다.

 

- 마스터에 해당 속성이 존재해 현재 데이터를 관리하고, 속성 그룹의 이력 데이터는 별도의 엔터티에서 관리 

- 마스터에 해당 속성이 존재하지 않고, 별도의 엔터티에서 속성 그룹의 현재+과거 데이터를 통합해서 관리 

- 마스터에 해당 속성이 존재하지 않고, 속성 그룹을 두 개의 엔터티를 사용해 현재와 과거 데이터를 개별로 관리

 

이 방법은 네 번째 방법과 유사한데요.

 

제 기준으로는 내역 엔터티인데, 비교해서 보는 게 이해를 돕기 때문에 10가지의 이력 엔터티 설계에 포함시켰습니다. 여덟 번째 방법, 마지막 열 번째 방법과 비교해 보세요.

 

유사한 속성을 묶어서 별도의 엔터티에서 현재+과거 데이터를 통합 관리하는 모델이 [그림1]입니다.



[그림1]

 

발행가는 변하지 않기 때문에 주식종목 엔터티에서 관리하고요. 변할 가능성이 있는 속성만을 묶어서 별도의 엔터티에서 관리합니다.

 

별도의 엔터티에서 현재+과거 데이터를 통합해 관리하므로 엔터티명에 ‘~이력’을 붙이지 않습니다.

 

이전 방법과 마찬가지로 일대일(1:1) 관계로 도출해야 하는 요건과 잘 연계하면 더욱 효율적인 모델을 설계할 수 있습니다.


블로그 이미지

블루퍼필

댓글을 달아 주세요

이력 데이터를 설계하는 방법이 이제 곧 마무리될 거 같습니다.

시리즈 글 10개 올리는 게 쉽지 않네요. ㅎㅎ

 

이력 데이터를 설계하는 유형을 정리하면 크게 아래 세 가지입니다.

 

- 전체 속성을 관리(인스턴스 단위)

- 속성 하나 하나를 관리(속성 단위)

- 유사한 속성을 묶어서 관리(속성 그룹 단위)

 

위의 두 가지는 이미 설명드렸고 마지막 유형만 남았습니다.

 

마지막 유형인 유사한 속성을 묶어서 설계하는 방법은 다시 세 가지로 구분할 수 있습니다.

 

- 마스터에 해당 속성이 존재해 현재 데이터 관리, 속성 그룹의 이력 데이터는 별도의 엔터티에서 관리

- 마스터에 해당 속성이 존재하지 않고, 속성 그룹을 별도 하나의 엔터티를 사용해 현재+과거 데이터를 통합해서 관리

- 마스터에 해당 속성이 존재하지 않고, 속성 그룹을 두 개의 엔터티를 사용해 현재와 과거 데이터를 개별로 관리

 

위 방법은 유사한 속성을 묶어서 설계한다는 것을 제외하고 속성을 개별 엔터티에서 관리하는 방법(세 번째, 네 번째, 다섯 번째)과 동일합니다.

 

이 방법은 성격이 유사한 속성을 같이 관리하는 것인데요.

 

주로 도메인 유형이 같은 속성을 같이 설계합니다.

또는 같이 조회되는 요건이 명확하다면 해당 속성을 같이 설계하고요.

동시에 입력되는 속성도 같이 설계할 수 있고요.

일대일 관계로 관리할 수 있는 요건이면 이 유형으로 설계할 수 있습니다.

 

[그림1]은 모든 종목 속성을 마스터인 종목 엔터티에서 관리하며 가격과 관련된 속성은 별도의 가격 이력 엔터티에서, 이름과 관련된 속성은 별도의 이름 이력 엔터티에서 관리하는 모델입니다.



[그림1]

 

주식종목 엔터티의 가격 속성(주식종목가격이력 엔터티에 속한 속성) 중에서 하나라도 바뀌면 이력 데이터를 생성합니다.

 

예를 들어 장이 끝나고 다음날 기준가가 바뀌면 주식종목 엔터티의 기준가 속성은 업데이트되고, 변경되기 전의 기준가는 주식종목가격이력 엔터티에 인서트됩니다.

 

이때 다른 가격 속성(발행가·액면가)은 변경되지 않는다고 가정하면 주식종목 엔터티의 값과 일치합니다. 변경되지 않은 속성은 널(Null)로 인서트할 수도 있지만(이렇게 하면 변경된 속성을 알 수 있음) 같이 조회될 수 있다는 요건을 만족하기 위해 변경되지 않은 속성도 데이터를 그대로 인서트합니다.

 

물론 주식종목이름이력 엔터티에는 데이터를 인서트하지 않습니다.

 

[그림2] 인스턴스는 사례 데이터입니다. 2026115일에 기준가가 16000에서 17000으로 변했을 때의 인스턴스입니다.


[주식종목]

#주식종목번호

주식종목

한글단축명

주식종목

영문단축명

발행주식수

발행일자

발행가

액면가

기준가

1000

홍길동사

HONG

100

2025-12-31

6000

5000

17000


[주식종목가격이력]

#주식종목번호

#변경일자

발행가

액면가

기준가

1000

2026-01-15

6000

5000

16000

 

[그림2]

 

[그림1]과 같은 예제 모델은 일반적인 방법이고 좀 더 전략적으로 설계할 수 있습니다.

 

예를 들어 변경되지 않는 속성은 이력 엔터티에서 관리하지 않는다든지…

매우 빈번히 변경되는 속성과 변경될 가능성이 적은 속성으로 분리할 수도 있고요.

외부에서 데이터를 받는다면, 동시에 받는 속성만을 별도 이력 엔터티에서 관리할 수도 있고요.

 

[그림1] 모델에서 발행가는 변경되지 않으니 주식종목 엔터티에서 관리하고, 변할 수 있는 가격(액면가·기준가)만 이력에서 관리할 수 있습니다.

 

이 경우 더욱 정밀한 분석이 필요하고 물론 더 판단할 게 있습니다.

 

조회가 같이 되느냐와 정정인데요.

 

변경되느냐와는 무관하게 조회가 같이 되는 속성이라면 같은 엔터티에 위치하는 게 좋을 수 있고요.

 

원래는 변하지 않는 게 맞지만 잘못 입력한 정정 데이터를 고려해야 할 때가 많습니다. 정정에 대해서는 별도로 설명하겠습니다.

 

어쨌든 조회 요건과 정정 요건은 고려해야 할 요소입니다.

 

속성별로 하나의 엔터티에서 관리하는 방법(세 번째, 네 번째, 다섯 번째)은 엔터티가 늘어나는 단점이 있었지만 이 방법은 엔터티의 정체성도 비교적 좋고 엔터티도 많이 늘어나지 않습니다.

 

일대일(1:1) 관계의 엔터티와 연계해서 이력 데이터를 설계하기도 좋고요.

모델로 업무 파악하기에도 비교적 좋아 적절하게 사용하면 효율적인 모델이 됩니다.

 


 

블로그 이미지

블루퍼필

댓글을 달아 주세요

일곱 번째 방법은 여섯 번째 방법의 확장입니다.

 

엔터티 한 개만 관리하는 여섯 번째 방법에서 두 개의 엔터티로 확장한 모델이 [그림1] 입니다.


[그림1]

 

고객계좌통합번호 속성은 배타 관계(계좌와 고객 엔터티)를 관리하는 속성입니다. 엔터티번호 속성과 함께 사용해야 어떤 엔터티의 식별번호인지를 알 수 있습니다(파란 속성은 같이 사용하는 쌍을 의미).

 

계좌 엔터티만이 아니라 다른 엔터티의 이력 데이터도 관리하므로 포괄적으로 속성통합이력 엔터티라고 붙이고요([그림1]처럼 단 두 개의 엔터티라면 고객/계좌속성이력도 좋음).

 

이력엔터티라는 엔터티에서는 이력 데이터를 관리하는 대상 엔터티를 관리합니다.

 

이 방법은 여섯 번째 방법의 단점은 모두 가지고 있으며 더 유연하기 때문에 업무를 파악하기 더욱 어려워진다는 단점이 추가되지만, 엔터티별로 속성 이력 엔터티(계좌이력·고객이력 엔터티)가 추가되는 것보다 효과적이라고 생각합니다. 간혹 작정하고 다소 어려운 모델을 사용해야 할 때가 있습니다.

 

최대한 유연하게 설계할 수 있다는 것이 최대의 장점입니다.

 

이력 데이터를 종테이블(Vertical Table)로 관리하는 대상 엔터티를 알 수 있다는 점도 장점이고요. 엔터티 개수가 줄어든다는 점도 장점입니다.

 

너무 많은 엔터티의 이력 데이터를 통합하는 것보다는 성격이 유사하거나, 같은 영역에 있는 몇 개의 엔터티를 통합하면 좋습니다.

 

이 방법은 이력 데이터를 관리하는 대상 엔터티의 주 식별자를 주의해야 합니다. 배타 관계를 관리하는 방법과 같습니다.

 

[그림1]은 주 식별자가 다른 대표적인 엔터티를 관리하는 예제로 고객계좌통합번호 속성 사용에 주의해야 하고요.

 

슈퍼타입, 서브타입을 이력 관리할 때는 주 식별자가 같아 [그림2]와 같이 배타 속성(고객번호)이 단순해집니다.


[그림2]

 

[그림1] [그림2]는 비교적 수월한데요.

 

대상 엔터티의 주 식별자가 다양(성격과 개수)할 때가 문제입니다.

 

[그림3]은 이 문제를 해결할 수 있는 매우 유연한 모델입니다.


[그림3]

 

이력 데이터를 관리하는 대상이 계좌·고객·고객주소 엔터티이고요. 각각 주 식별자(빨간 속성) 개수가 다릅니다.

 

통합 이력을 관리하는 엔터티(속성통합이력)는 배타 관계가 발생하고, 세 개의 속성(통합이력식별속성·통합이력식별속성2·통합이력식별속성3)에서 대상 엔터티의 주 식별자 값을 관리합니다.

 

주 식별자가 하나인 고객 엔터티의 속성이 변경되면 통합이력식별속성2·통합이력식별속성3 속성에 해당되는 값은 없으므로 널(Null) 허용입니다(속성 왼쪽 동그라미 표시).

 

[그림3]과 같이 하나의 엔터티에서 다양한 엔터티의 이력 데이터를 관리하는 요건을 경험한 적은 없습니다.

 

배타 관계 때문에 이와 유사한 모델이 발생한 적은 있는데요. 이에 대해서는 나중에 별도로 소개하겠습니다.

 

이상으로 이력 데이터를 종테이블(Vertical Table)로 관리하는 방법을 설명드렸는데요.

 

여섯 번째와 일곱 번째 모델이 유용할 때가 분명 있습니다. 이력 데이터를 조인해서 조회하는 게 아니고 필요 시 단지 추적 용도로 사용하면 효과적입니다.

 

하지만 분석하기 싫어서, 귀찮아서 이 모델을 선택한다면 안 될 것입니다. 특별히 모델러는 주의해야 합니다.


블로그 이미지

블루퍼필

댓글을 달아 주세요

이번 시간에는 속성 단위로 이력 관리하는 방법을 정리하는 의미로 다양한 예제를 설명드리겠습니다. 처음부터 다시 읽지 않으려면 잘 따라오셔야 합니다. ㅎㅎ

 

세 번째, 네 번째, 다섯 번째 방법처럼 한 속성만으로 이력 데이터를 설계하는 방법은 역할(Role)을 관리할 때 자주 사용합니다. 실체 엔터티 간 관계(역할)는 주로 별도의 엔터티에서 관리합니다.

 

계좌 관리 사원을 관리한다면 [그림1]과 같은 모델이 기본입니다.



[그림1]

 

위 모델에서 변경된 과거 관리 사원까지 관리한다면 [그림2]와 같이 됩니다.


[그림2]

 

계좌관리사원 엔터티에서 현재 계좌를 관리하고 있는 사원과 과거에 관리했던 사원을 함께 관리합니다. 현재 데이터도 관리하므로 ‘~이력’이란 단어를 엔터티명에 사용하지 않았고요.

 

역할을 관리하는 엔터티는 보통 조회 성능을 고려해야 합니다. 특정 계좌의 특정일 관리 사원에 대한 조회는 문제가 안 되지만 계좌를 가장 많이 관리하고 있는 ‘홍길동’이라는 사원의 전체 계좌에 대해 계좌번호와 잔고 등의 기본 데이터를 보여주는 화면이 존재하거나, 지점별로 관리자가 관리하는 계좌 숫자와 예수금 총액을 보여주는 화면 등이 있다면 성능 문제가 발생할 수 있습니다.

 

일반적으로 고객에게 제공하는 화면에는 문제가 없지만 사용자(직원)에게 보여주는 화면에 성능 문제가 있을 수 있습니다.

 

이때 선분 이력을 검토해야 합니다. 이번 시리즈에서는 변경일자만 사용하고, 실제로 변경일자만 관리해도 조회 성능 문제가 크지 않지만 요건에 따라 차이가 커질 수 있습니다.

 

선분 이력의 성능 문제는 다음 글을 참조해 보세요(오픈메이드컨설팅 오동규님의 글입니다).

 

3 - 변경이력 테이블에 종료일자가 필요한가?
 

성능 문제를 해결하는 다른 방법은 비정규형입니다. [그림3] 모델과 같이 계좌 엔터티에 현재 관리 사원을 중복으로 관리할 수 있습니다.



[그림3]

 

이때 현재계좌관리사원번호 속성은 추출(Derived) 속성입니다. 계좌관리사원 엔터티에 존재하는 데이터 중 가장 최근에 관리 사원으로 지정된 사원, 즉 현재의 관리 사원을 계좌 엔터티에 추출 관계로 관리하는 것입니다.

 

계좌관리사원 엔터티에도 계좌의 현재 관리 사원 데이터가 존재하고 이 값이 원천 데이터입니다.

 

현재 역할이 중요하므로 대부분 요건은 현재 관리 사원과 관련돼 계좌 엔터티만으로 처리할 수 있습니다.

 

비록 무결성 저해 요소가 생기더라도 데이터 중복을 선택하는 것이 바람직할 때도 있습니다. 데이터 무결성(Integrity)이 최우선 요소지만 무조건 항상 그런 것은 아니라는 점이 어렵습니다.

 

[그림3] 모델에서 만약 계좌 엔터티에서는 현재 관리 사원만 관리하고 과거 관리 사원은 계좌관리사원 엔터티에서 관리한다면 [그림4]와 같은 모델이 될 것입니다.


[그림4]

 

과거 데이터만 관리하는 엔터티는 구분하기 위해 ‘~이력’을 붙여 계좌관리사원이력 엔터티명을 사용하고, 계좌 엔터티의 현재계좌관리사원번호 속성도 ‘현재’라는 단어를 굳이 안 붙여도 됩니다. 현재•최근•최초 등의 단어가 사용되면 일반적으로 추출 속성입니다.

 

하지만 [그림4] 모델에는 커다란 결점이 있습니다. 계좌와 사원 사이에는 관계(Role)가 하나만 존재하는 것은 아니라는 겁니다.

 

운용•실적•상담 사원 등이 존재할 수 있는데 이런 다양한 역할(Role) [그림4]와 같은 모델로 관리하는 것은 확장성이 떨어집니다.

 

미래에(아마도 가까운 미래에) 다른 역할이 존재하면 스키마가 변경됩니다. 계좌 엔터티가 변경되고, 관리자와 연관된 화면이나 프로그램도 많아 유지보수가 어려워집니다.

 

그래서 [그림5]와 같이 계좌관계사원 엔터티에서 여러 역할을 통합해 관리할 수 있습니다.



[그림5]

 

여러 역할을 통합 관리하므로 엔터티명과 속성명에 좀 더 일반적인 용어(관계사원)를 사용했습니다.

 

[그림5] 모델에서 현재의 관계 사원 데이터를 추출 속성으로 관리하려면 [그림6]과 같은 모델이 됩니다.



[그림6]

 

관리•운용•실적•상담 사원 중에서 관리 사원과 실적 사원만을 추출 속성으로 관리했습니다. 추출 속성은 주요한 일부 속성만을 사용해야 유지 보수가 수월해집니다. 모든 역할 속성을 추출 속성으로 관리한다면 확장성이 현저히 떨어지게 되고요.

 

이렇게 사원과 계좌 사이에는 역할로서 관계가 존재하는데 여러 역할이 존재할 수 있습니다. 역할은 부여하기에 따라 얼마든지 늘어날 수 있다는 사실을 염두에 두어야 합니다.

 

또한 거의 모든 데이터는 변하기 때문에 과거 이력 데이터를 고려해야 하는데요. 관리 사원이나 실적 사원같이 역할(Role)을 관리하는 데이터는 보통 과거 데이터도 철저하게 관리하게 됩니다.

 

역할(Role)의 확장성과 역할의 이력 데이터를 고려해서 모델을 설계해야 합니다.

 

다음에는 이력 엔터티를 설계하는 여섯 번째 방법, 변경 대상 속성을 코드로 관리하는 방법에 대해 설명하겠습니다.

 


블로그 이미지

블루퍼필

댓글을 달아 주세요

이력 엔터티를 설계하는 다섯 번째 방법은 간단합니다. 앞의 두 방법의 혼합입니다.


-마스터에 해당 속성이 존재해 현재 데이터를 관리하고 이력 데이터는 별도의 엔터티에서 관리
-마스터에 해당 속성이 존재하지 않고 별도의 한 엔터티에서 현재+과거 데이터를 통합해서 관리
-마스터에 해당 속성이 존재하지 않고 별도의 두 엔터티에서 현재와 과거 데이터를 개별로 관리

 

[그림1]과 같이 현재 비밀번호를 관리하는 엔터티가 있고, 변경된 과거 비밀번호를 관리하는 엔터티가 있습니다.


[그림1]

 

이 모델에서 계좌비밀번호 엔터티는 발생 내역을 관리하는(발생일자 존재) 엔터티이고, 계좌비밀번호이력 엔터티는 변경 이력을 관리하는(변경일자 존재) 엔터티입니다.

 

최초에 발생한 비밀번호를 관리하는 계좌비밀번호 엔터티는 계속 업데이트되고요. 변경 시점에 이전 비밀번호는 계좌비밀번호이력 엔터티에 인서트됩니다.

 

계좌비밀번호이력 엔터티는 변경된 과거 데이터만을 관리하므로 엔터티명에 ‘~이력’이 붙었습니다. 이미 계좌비밀번호 엔터티가 있으니 더욱 적절하고요.

 

이 방법은 현재와 과거 데이터를 분리하는 세 번째 방법과 개념적으로 유사합니다. 그렇지만 계좌 비밀번호는 업무에서 많이 사용된다는 점에서 계좌 엔터티에 포함되는 모델(세 번째 모델)이 더 현실적입니다. 보안 때문에 엔터티를 분리해야 된다면 [그림1] 모델처럼 사용해야 하겠고요.

 

현재와 과거 데이터를 같이 관리하는 네 번째 방법에 비해 엔터티가 하나 늘어서 관리하기 상대적으로 어려워지고요.

 

데이터를 성격에 따라 분리했으므로, 즉 비밀번호라는 데이터를 별도의 엔터티에서, 과거와 현재로 분리해서 관리하므로 데이터 성격은 가장 명확해집니다. 지금까지 설명드린 방법에 비해 확장성이 좋아진다는 것을 의미합니다.

 

엔터티의 성격이 명확해지면 모델을 보고 업무를 파악하기 더욱 쉬워지고 커뮤니케이션에 많은 도움을 준다는 장점이 부가적으로 존재합니다.

 

반면에 속성의 명확한 정의가 선행돼야 하므로(속성별로 원천·이력 데이터를 분석하고 설계해야 하므로) 모델러에게는 힘든 방법입니다. 모델링 기간도 늘어나고요.

 

별도의 엔터티에서 하나의 속성 값 데이터를 관리한다는 것은 해당 데이터가 그만큼 중요하다는 것을 의미합니다. 데이터가 중요하게 자주 사용될 때 고려해야 합니다. 중요하지 않은 요건에 남발하면 속성별로 하나의 이력 엔터티가 생길 수 있어 꼭 필요하다고 판단될 때만 적용해야 합니다.

 

이상으로 변경된 하나의 속성만을 설계하는 방법(세 번째, 네 번째, 다섯 번째)까지 설명했습니다.


블로그 이미지

블루퍼필

댓글을 달아 주세요

이력 엔터티를 설계하는 네 번째 방법입니다.


-마스터에 해당 속성이 존재해 현재 데이터를 관리하고 이력 데이터는 별도의 엔터티에서 관리
-마스터에 해당 속성이 존재하지 않고 별도의 한 엔터티에서 현재+과거 데이터를 통합해서 관리
-마스터에 해당 속성이 존재하지 않고 별도의 두 엔터티에서 현재와 과거 데이터를 개별로 관리

 

비밀번호가 계좌 비밀번호와 홈페이지 비밀번호, ARS 비밀번호가 존재하면 [그림1]과 같이 설계할 수 있는데요.


[그림1]


어떤 종류의 비밀번호가 더 생길지 모르니 정규화를 하면
[그림2] 엔터티와 같아질 것입니다.



[그림2]
 

[그림2]가 원천 데이터를 설계한 모델입니다.

 

마스터 엔터티인 계좌 엔터티에는 비밀번호 속성이 존재하지 않고요. 여러 비밀번호를 구분하기 위해 계좌비밀번호 엔터티에 비밀번호구분코드 속성이 필요하고요.

 

계좌비밀번호 엔터티에서 관리하는 데이터는 내역 데이터입니다.  그냥 쌓이는 데이터이니까요. 이 엔터티가 내역 데이터라는 건 어렵지 않죠.

 

그런데 바뀐 비밀번호를 엔터티로 어떻게 관리하느냐에 따라 두 가지로 나뉩니다. [그림2] 모델에서 계좌비밀번호이력 엔터티를 추가할 수 있고요. 다음에 설명할 다섯 번째 방법이고 이해하는 데 어렵지 않습니다.

 

나머지 하나가 지금 설명할 방법인데요. 모델 자체는 [그림3]과 같이 어렵지 않습니다. [그림2]의 원천 엔터티에 과거 데이터까지 고려한 모델입니다.

 

[그림3]

 

그런데 [그림3]의 계좌비밀번호 엔터티도 내역 데이터라는 게 다소 혼란스럽습니다(제가요). 계좌의 속성인 비밀번호가 별도의 엔터티에 계속 쌓이는 형식이니까요.

 

계좌비밀번호 엔터티의 입장에서 보면 비밀번호가 일자대로 쌓이는 것이지 변경되는 것은 아니어서 저는 내역 엔터티로 봅니다. 변경 이력 엔터티에서 보이는 업데이트도 없고요.

 

제가 지속적으로 설명했지만 이렇게 구분하는 게 의미가 있습니다. 저도 헷갈릴 때가 있지만 90% 이상은 엔터티가 정확하게 도출됩니다.

 

별도의 한 엔터티에서 현재+과거 데이터를 통합해서 관리하는 방법으로 과거의 데이터만을 관리하는 것이 아니므로 엔터티명에 ‘~이력’이란 단어를 사용하지 않았습니다.

 

[그림3] 모델은 현재의 비밀번호를 조회하기가 다소 불편합니다.

 

비밀번호는 자주 사용되는 속성이라 실무에서는 주로 현재의 비밀번호를 바로 알 수 있도록 설계합니다. 이전에 설명한 세 번째 방법과 다음에 설명할 다섯 번째 방법으로요.

 

자주 사용되지 않는 속성을 대상으로 이 방법을 사용하면 좋습니다. 마스터 엔터티인 계좌 엔터티에도 영향을 미치지 않고, 별도의 이력 엔터티를 관리할 필요가 없어서 편합니다(엔터티 개수가 많아진다는 것은 좋지 않다는 점을 항상 염두에 두어야 합니다).

 


블로그 이미지

블루퍼필

댓글을 달아 주세요

이력 엔터티를 설계하는 첫 번째 방법은 하나의 엔터티에서 과거와 현재(미래)의 데이터를 함께 관리하는 것입니다.

 

[그림1] 수수료율 엔터티에는 계좌의 종류에 따라, 어떤 방법으로 거래했는지에 따라 달라지는 수수료율을 관리합니다. 이 엔터티는 현재의 수수료율뿐만 아니라 과거의 수수료율도 함께 관리합니다.

 

[그림1]

 

이 경우 변경 일자를 관리하게 되는데요. [그림1]과 같이 변경일자 속성이든 입력일자•시작일자 속성이든요. 이력 엔터티 시리즈 글에서는 편의상 변경일자 속성을 일괄적으로 사용하겠습니다.

 

사실 변경일자 속성이 적절한지는 아직도 고민 중입니다. 현재 인스턴스에 대해서는 입력 일자가 과거 인스턴스에 대해서는 변경 일자가 명확한데, 합치게 되니 어떤 게 더욱 적절할지 고민입니다.

 

이 고민은 엔터티를 이렇게 사용하면 안 되는 게 아닌가 하는 고민으로 번지기도 하는데요. 어쨌든 현재는 변경일자 속성으로 사용하겠습니다.

 

참고로 종료일자 속성에 대해서는 지난번 글을 참고해 보세요.

 

선분 이력의 종료일자

 

하나의 엔터티에서 현재와 과거 데이터를 같이 관리하는 주요한 이유는 과거 데이터에 대한 사용 빈도가 높기 때문입니다. 수수료율이나 환율을 관리하는 엔터티는 과거 특정 시점의 값이 어떠했는지를 알려는 요건이 빈번하게 존재할 수 있습니다.

 

과거 데이터도 빈번하게 사용되며, 때로는 현재 데이터와 동시에 사용될 때도 있다면 하나의 엔터티에서 현재와 과거 데이터를 관리하는 것이 효율적입니다.

 

반면에 대부분 현재 데이터가 사용되고 과거 데이터는 거의 사용되지 않아 두 종류의 데이터가 같이 사용될 가능성이 없을 때는 과거와 현재 시점의 데이터를 분리하는 게 좋고요.

 

하나의 엔터티에서 현재와 과거 데이터를 관리하면 데이터 모델(ERD)을 관리하기 편한데요. 이는 큰 장점이어서 만약 양쪽 모델의 장•단점이 명확하지 않다면 모델의 변경(형상) 관리를 위해 하나의 엔터티에서 현재와 과거 데이터를 관리하는 모델을 사용하는 게 좋습니다.

 

이와 유사하게 현재와 과거 데이터가 같이 존재해도 별 이상이 없다면 하나의 엔터티에서 관리하는 것이 좋습니다. 이런 엔터티는 주로 중요도가 떨어지는 엔터티일 겁니다.

 

현재와 과거 데이터를 하나의 엔터티에서 관리하는 모델의 가장 큰 단점은 하위(자식) 엔터티를 가질 수 없어 확장성이 떨어진다는 것입니다.

 

[그림2]의 주문 엔터티는 현재와 과거 데이터를 함께 관리하는 엔터티인데요. 설명을 위해 만든 엔터티이지 일반적인 엔터티는 아닙니다.




[
주문]

#주문번호

#변경일자

배송처

100

2025-05-01

서울

 

[주문상품]

#주문번호

#변경일자

#상품코드

주문수량

100

2025-05-01

1010

1

100

2025-05-01

1020

3

100

2025-05-01

1050

2


[
그림2]

 

‘100’번 주문의 배송처는 서울이고 3개의 상품을 주문했습니다. 그런데 배송처가 서울에서 경기도로 변경되면 아래의 [주문] 릴레이션 같이 새로운 인스턴스가 생성됩니다.

 

[주문]

#주문번호

#변경일자

배송처

100

2025-05-01

서울

100

2025-05-02

경기


[
그림3]

 

그런데 위의 릴레이션처럼 관리하면 주문 상품 데이터가 이상해집니다(데이터 아노말리는 아니지만요). [그림4] 릴레이션을 보면 현재의 주문인 ‘100’번 주문의 주문 상품이 무엇인지 쉽게 알 수 없습니다.

 

[주문]

#주문번호

#변경일자

배송처

100

2025-05-01

서울

100

2025-05-02

경기

 

[주문상품]

#주문번호

#변경일자

#상품코드

주문수량

100

2025-05-01

1010

1

100

2025-05-01

1020

3

100

2025-05-01

1050

2


[
그림4]

 

[주문] 엔터티에는 현재의 주문 데이터가 2025 5 2일 발생한 데이터인데, [주문상품] 엔터티에는 여전히 2025 5 1일 발생한 데이터로 남아 있어 연관 관계가 끊어졌습니다.

 

사실 [주문] 릴레이션에서 최초 주문을 찾으면 해당하는 [주문상품] 릴레이션을 찾을 수 있어 연관 관계가 아주 끊어진 것은 아니지만, 희미하게 남아 있는 것이라 조회하기 불편합니다.

 

따라서 [그림5]와 같이 [주문상품] 릴레이션도 변경시켜 주어야 합니다. [주문상품1] 릴레이션은 [주문] 릴레이션의 최신 인스턴스에 해당하는 변경일자 값으로 업데이트한 것이고 [주문상품2] 릴레이션은 기존의 인스턴스는 그대로 두고 새로운 인스턴스를 생성한 것입니다.

 

[주문상품1]

#주문번호

#변경일자

#상품코드

주문수량

100

2025-05-02

1010

1

100

2025-05-02

1020

3

100

2025-05-02

1050

2

 

[주문상품2]

#주문번호

#변경일자

#상품코드

주문수량

100

2025-05-01

1010

1

100

2025-05-01

1020

3

100

2025-05-01

1050

2

100

2025-05-02

1010

1

100

2025-05-02

1020

3

100

2025-05-02

1050

2

 

[그림5]

 

실전에서 주로 [주문상품1] 릴레이션처럼 사용되지만, 하나를 선택해야 하는 상황이라면 [주문상품2]가 더 좋을 거 같고요. 주문 상품의 이력 데이터도 고려해서요. 물론 두 가지 모두 결코 좋은 방법은 아닙니다.

 

주문상품 엔터티 같은 하위(자식) 엔터티가 소수일 때는 그나마 관리할 수 있을지 모르지만 하위 엔터티는 어떻게 늘어날지 모르므로 기본적으로 관리가 안 되는 방법입니다.

 

따라서 하위(자식) 엔터티가 하나라도 존재할 때는 하나의 엔터티에서 변경 데이터를 같이 관리하는 것을 피해야 합니다.

 

실무에서 비교적 자주 볼 수 있는데요. 만약 하위 엔터티의 데이터를 전부 쫓아가서 업데이트하거나 인서트해야 하는 상황이라면 일단 모델이 잘못됐다고 생각하면 됩니다. 여러 편법도 있는데 해석을 한번 거쳐야 되는 모호한 모델도 잘못됐다고 생각하면 됩니다.

 

그밖의 특징을 보면요. 하나의 엔터티에서 현재와 과거 데이터를 관리하는 방법은 인스턴스 단위로 변경 관리하므로 변경된 속성만을 찾을 수가 없는 것이 단점입니다. 반면에 해당 인스턴스의 전체 속성을 조회할 때는 효율적이고요.

 

또한 변경되지 않은 전체 속성까지 스냅샷 상태로 보관하므로 변경된 속성 단위로 관리하는 방법보다 많은 중복 데이터가 발생해 용량을 많이 차지하고요.

 

데이터가 하나의 엔터티에 집중돼 조회 또한 집중적으로 발생한다는 점도 고려해야 합니다.

 

그리고 현재와 과거 데이터가 한 엔터티에서 관리되면 엔터티의 성격이 불명확해지는 경향이 있습니다. 내역과 이력을 같이 관리하기 때문인데요. 이는 어떤 면에서는 가장 커다란 단점일 수 있습니다.

 

원천 엔터티를 명확히 하는 것이 우선입니다. 이게 깨지면 다 소용 없게 되죠. ㅎㅎ

 

핵심적인 실체•행위 엔터티는 하나의 엔터티에서 현재와 과거 데이터를 관리하는 방법이 대개 바람직하지 않습니다.

 

마지막으로 [그림1]과 같이 하나의 엔터티에서 과거와 현재 데이터를 관리할 때는 엔터티명에 ‘~이력’을 사용하지 않는 것이 일반적입니다. 다음에 설명할, 과거 데이터를 별도로 관리할 때만 엔터티명에 ‘~이력’을 붙입니다.

 


블로그 이미지

블루퍼필

댓글을 달아 주세요

이력 데이터에 대한 글을 계속 올리고 있는데요. 개요적인 내용은 소개했으니 다른 주제(식별자)로 넘어갈까를 좀 고민했습니다. 느끼신 분들이 있겠지만 엔터티나 관계 등과 같이요.

 

개인적으로 제가 책을 쓰면서 다른 책과 차별되도록 구성한 장이 정규화와 통합, 이력, 방법론 입니다. 얼마 전에 메일을 한통 받았는데 거의 정확하게 맞추신 분이 있습니다. 각 장의 특징을 조만간 올릴 생각입니다. 군더더기라 생각해서 책에는 생략을 했는데요.

 

이력 데이터 관리가 전략적인 장이라서 당분간 이력 엔터티 위주로 글을 올리겠습니다. 오늘은 이력 데이터를 관리할 수 있는 10가지 방법의 개략에 대해 쓰려고 합니다.

 

10가지 방법은 실무에서 자주 사용하는 방법을 제 나름대로 구분한 것인데요. 사실 내역 데이터 설계 방법까지 일부 포함돼 있습니다. 이력과 내역은 데이터의 성격이 아니라 엔터티의 설계 형태에 따라 구분되기도 합니다.

우선, 크게 3가지로 구분할 수 있습니다.

 

엔터티의 속성 중에서 하나라도 변경되면 변경 전의 전체 인스턴스를 그대로 관리하는 방법과 변경된 속성만을 개별적으로 관리하는 방법. 그리고 유사한 성격의 속성을 묶어서 관리하는 방법이 있습니다.

 

인스턴스를 통째로 쌓는 방법은 다른 방법에 비해 저장 공간의 낭비가 심합니다. 비록 특수 목적을 위한 것이지만 중복이 심하고요.

 

저장하기 쉽고 해당 시점의 전체 데이터, 즉 변경된 속성의 데이터와 변경되지 않은 속성의 데이터를 한 번의 액세스로 조회하기 쉽다는 강력한 장점이 있습니다. 하지만 어떤 속성 값이 변경됐는지 알기 어려워 변경된 속성의 데이터만을 조회하기는 쉽지 않습니다.

 

변경된 속성의 데이터만을 관리하는 방법은 저장 공간이 가장 절약됩니다. 또한 변경된 속성만을 대상으로 관리하므로 변경된 속성이 무엇인지 명확하게 알 수 있습니다.

 

반면에 변경된 속성의 데이터와 변경되지 않은 속성의 데이터를 같이 조회하기는 쉽지 않습니다. 인스턴스로 쌓는 방법과 장·단점이 대체로 반대입니다.

 

마지막으로 속성 중 내용(도메인)이 유사하거나 같이 사용될 수 있는 속성만으로 별도의 엔터티를 만들어서 해당 속성 중의 하나라도 변경되면 그 시점의 데이터 인스턴스를 스냅샷으로 관리하는 방법이 있습니다.

 

인스턴스로 관리하는 방법과 개별 속성으로 관리하는 방법의 장점을 수용한 방식으로 적절하게 사용하면 양쪽의 장점을 살리는 것이 되겠지만 잘못 사용되면 단점만을 수용하게 될 수도 있습니다.

 

유사한 성격의 이력 데이터가 하나의 엔터티에서 관리되므로 엔터티의 성격이 분명해지는 장점도 있어 요건에 따라서는 가장 효율적인 방법입니다.

 

이상이 이력 데이터를 관리는 커다란 3가지 방법이고요. 다음부터 상세하게 10가지로 나눠 설명하겠습니다. 시리즈 비슷하게요.

 

그리고 나중에도 언급하겠지만 이력 데이터를 관리하는 방법을 하나로 획일화하려는 경향이 있습니다. 모든 이력 데이터를 스냅샷 방법으로 처리한다거나 개별 속성으로 관리한다고 정하는 것은 전혀 바람직하지 않습니다. 엔터티의 성격과 요건, 중요도에 맞춰 적절한 방법을 사용해야 합니다.

 

이력 데이터에 대한 요건은 현재도 단순하지 않지만 앞으로 더욱 복잡해지고 어려워질 것이므로 요건에 가장 합당한 방법을 채택할 수 있는 힘을 길러야 합니다. 이런 힘을 길르는 데 초점을 맞춰 10가지 방법을 고민해보면 좋을 거 같습니다.


블로그 이미지

블루퍼필

댓글을 달아 주세요

[그림1]은 이력 엔터티 확정 절차입니다.



[그림1]

 

가장 먼저 해야 할 일은 이력 데이터를 관리해야 하는지를 분석하는 것입니다. 이력(지나간 과거) 데이터를 사용하는 업무가 없다면 이력 데이터 관리 요건은 없는 것입니다. 그냥 기존 데이터를 최신 데이터로 업데이트하면 끝입니다. 속 편하게 그냥 업데이트하고 싶지만 업무가 그렇게 간단하지 않습니다.

 

변경된 과거 데이터를 관리해야 하는지에 대해서는 현업의 의견이 가장 중요한 기준이 됩니다. 동종 업체의 업무를 참조할 수도 있고요.

 

현업의 판단이 이력 데이터는 필요 없다는 것이라도 모델러가 판단하기에 필요하다고 생각되면 이력 엔터티를 채택할 수도 있습니다.

 

당장에는 사용하지 않지만 이력 데이터를 쌓아 두면, 업데이트해서 이전 데이터를 없애는 대신 저장해서 새로운 인스턴스로 쌓아 두면 추후에 유용하게 사용될 수 있습니다. 데이터의 중요도를 고려해야 하지만 가능한 순수 업데이트와 삭제는 없도록 하는 것이 좋습니다.

 

그리고 현업의 요건과는 무관하게 IT 담당자 입장에서 이력 데이터를 보관해야 할 때도 있습니다. 잘못된 작업의 복구나 잘잘못을 따지기 위해 필요할 수 있습니다.

 

이렇게 분석해서 변경 데이터를 관리해야 하는 요건이 있다면 이력 관리 대상 엔터티가 됩니다.

 

다음은 이력 데이터를 어떤 방법으로 관리하는 것이 가장 효율적일지를 고려해야 합니다. 이력 데이터를 관리하는 방법은 크게 다섯 가지가 있으며 자세한 내용은 이어서 설명하겠습니다.

 

이력 모델 유형을 결정하는 단계가 가장 어려운 단계입니다. 대부분은 거의 기계적으로 이력 모델 유형을 결정할 수 있지만 때에 따라서는 판단하기 까다로울 수 있습니다. 엔터티 정의(본질 데이터 정의가 어려우면 이력 데이터는 정의하기 더욱 어려움)나 중복 데이터 등과 연관돼 기준이 흔들릴 때가 있습니다.

 

이력 관리 유형이 정해졌으면 그다음으로는 선분 이력을 채택할지를 결정합니다. 선분 이력은 이력 모델 유형과도 연관 있어 이력 모델 유형을 결정하면서 동시에 이루어질 수 있습니다.

 

성능 이슈가 없다면 일반 이력 엔터티(변경일자 존재)를 채택하고 성능 문제가 발생할 가능성이 있다면 선분 이력 엔터티(시작일자•종료일자 존재)를 채택해야 합니다. 이전 글에서 언급했지만 선분 이력(종료일자)을 무조건 채택하는 것은 바람직하지 않습니다.

 

마지막으로 이력 엔터티의 주 식별자(PK)를 확정합니다. 이 단계도 이력 모델 유형을 결정하거나 선분 이력을 고민하면서 함께 이루어지기도 합니다.

 

물론 여기서의 주 식별자는 자신 엔터티 입장에서 확정하게 됩니다. 많진 않지만 추후에 하위 엔터티까지 고려해서 주 식별자가 바뀔 수도 있습니다.

 

주 식별자를 확정하면 이력 엔터티가 확정됩니다.

 


블로그 이미지

블루퍼필

댓글을 달아 주세요