2012-07-02 3 views
5

개정 내역을 유지하기위한 DB 설계의 일반적인 전략은 무엇입니까? 내가 다루고있는 것이 하나의 테이블이라면 그렇게 어렵지 않을 것이라고 생각합니다. 각 업데이트를 테이블에 새 레코드로 저장하면됩니다. 마지막 레코드는 항상 최신 개정판입니다.데이터베이스 디자인 : 기록을 추적하는 방법?

그러나 데이터가 여러 테이블에 걸쳐 저장되는 경우 개정판을 추적 할 수 있도록 데이터를 디자인하는 좋은 방법은 무엇입니까?

답변

2

각 버전 테이블에 대한 추가 기록 테이블을 선호합니다. time_fromtime_to 추가 필드가있는 주 테이블과 동일한 구조입니다. 투명하게 트리거로 채워집니다. 현재까지 최신 개정판 time_to이 설정되었습니다.

지정된 순간에 대한 국가는 다음과 같이 쿼리를 검색 할 수 있습니다 : 검색 또는 현재의 데이터를 결합 할 때 복잡한 조건을 필요로

나에게로
SELECT * FROM user_history 
WHERE time_from >= '2012-02-01' AND time_to <= '2012-02-01' 

는 메인 테이블 내 이력을 저장하는 것은 일반적으로 좋은 생각이 아니다 .

+0

따라서 주 테이블에는 최신 데이터가 있습니다. 그런 다음 "역사적인"테이블에는 각 개정 본의 사본이 있습니까? 이것은 정상화를 깨뜨리는가? – StackOverflowNewbie

+0

예, 비정규 화가 발생합니다 (단순한 INSERT, DELETE, 메인 테이블의 UPDATE로부터 히스토리 상태가 자동 생성됩니다). 최신 리비전의 성능을 나타냅니다 (예를 들어, 메인 테이블은 데이터를 기반으로 인덱스를 가지고 있습니다. 역사에는 날짜 색인이 있습니다). 최신 개정판이 주요 개정판이 아닌 경우이 접근법은 정규화가 손상 될 수 있습니다. – vearutop

0

MySQL의 binary logging을 켜고 사용하십시오.

+0

이 질문은 쿼리 가능한 기록에 관한 것 같습니다. – MaxSem

0

내가 처리하고있는 각 객체가 테이블 인 곳에서 시간이 지남에 따라 변경되는 경향이있는 테이블을 가지고있는 접근 방식을 사용하고 있습니다. 일반적으로 이러한 테이블은 다음 개념을 따릅니다.

  • 이름에 _HISTORY 접미사가 있습니다.
  • 개체 인스턴스의 수명을 나타내는 start_dtend_dt이라는 두 개의 추가 필드가 있습니다.
  • start_dtNOT NULL이고, end_dtNULL 일 수 있습니다. 이는 현재 인스턴스이며 현재 시간 제한이 없음을 나타냅니다.
  • 는, 당신은 31/Dec-2012 23:59:59 현재 인스턴스의 end_dt을 설정하고 1/Jan-2013 00:00:00start_dt에 새 레코드를 삽입해야합니다, 당신은 새로운 회사 이름 1/Jan-2013에서 활성화하고 싶은 말은 미래 일자 변경을 삽입 할 수있다;
  • 때때로 수정 버전을 추적해야하는 경우 revision 필드를 추가하십시오.

이러한 디자인에서 적절한 RI 제약 조건을 갖기 위해 나는 버전 관리 대상 객체에 대해 항상 2 개의 테이블을 가지고 있습니다. 내가 외래 키를 구축하는 customer(customer_id)를 사용하는 다른 모든 장소에서

customer (customer_id INTEGER, PRIMARY KEY (customer_id)); 
customer_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP, 
        name VARCHAR(50), sex CHAR(1), ..., 
        PRIMARY KEY (customer_id, start_dt)); 
customer_bank_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP, 
         bank_id INTEGER, iban VARCHAR(34)); 

: 말, Customer obejct 위해 나는 테이블의 다음과 같은 설정이있다.실제 고객 정보를 조회하는 것은 간단하다

SELECT c.customer_id, ch.name, ch.sex 
    FROM customer c 
    JOIN customer_history ch ON c.customer_id = ch.customer_id 
     AND now() BETWEEN ch.start_dt AND coalesce(end_dt, now()); 

왜 나는 그런 디자인을 선호 : 나는 디자인하여 데이터베이스 수준에서 개체 인스턴스를 버전이있다

  1. 을;
  2. 적은 테이블을 유지해야합니다.
  3. 누군가가 트리거를 삭제하거나 사용할 수 없게 된 경우 기록을 잃어 버릴 수 없습니다.
  4. 나는 미래의 변화를 쉽게 계획하고 유지할 수 있습니다.

희망이 도움이 될 것입니다.

0

어려운 부분은 "기본"테이블의 버전을 지정하는 것이 아닙니다. 하나의 테이블을 개별적으로 분리하기 때문에 버전을 개별적으로 버전화할 수 있습니다.

어려운 부분은 연결 사이에 있습니다.

특정 프로젝트의 요구 사항에 따라 정확히 어떻게 할 것입니까? 여기에 sales orders could be "historized"의 예가 있지만 다른 많은 변형이 가능합니다.

0

Datadiff. API 기반 DB 개정 추적.

전체 공개 :

나는 DATADIFF을 만들었습니다. SASS 제품을 지원하기 위해 MongoDB의 데이터 모델을 시각적으로 제공 한 솔루션이 필요했습니다. SQL 데이터베이스에서도 작동합니다.

key:val 표기법으로 기본 쿼리를 수행 할 수 있습니다. 즉 id:123