복붙노트

[SQL] 개정을위한 데이터베이스 설계?

SQL

개정을위한 데이터베이스 설계?

우리는 데이터베이스에있는 개체에 대한 모든 변경 (변경 내역)을 저장하는 프로젝트의 요구 사항을 가지고있다. 현재 우리는이 2 개 설계 제안이있다 :

예를 들면 "직원"엔티티에 대한

(1) 디자인 :

-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

-- Holds the Employee Revisions in Xml. The RevisionXML will contain
-- all data of that particular EmployeeId
"EmployeeHistories (EmployeeId, DateModified, RevisionXML)"

2 디자인 :

-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

-- In this approach we have basically duplicated all the fields on Employees 
-- in the EmployeeHistories and storing the revision data.
"EmployeeHistories (EmployeeId, RevisionId, DateModified, FirstName, 
      LastName, DepartmentId, .., ..)"

이 일을 어떤 다른 방법이 있나요?

은 "디자인 1"의 문제는 당신이 데이터에 액세스 할 필요가있을 때 우리가 구문 분석 XML 각 시간을 가지고있다. 이 과정을 느리게하고 또한 우리가 개정 데이터 필드에 조인을 추가 할 수 없습니다와 같은 몇 가지 제한을 추가합니다.

그리고 "디자인 2"의 문제는 우리가 (우리는 우리가 개정을 유지하려는 주위 70 ~ 80 개체가) 모든 엔티티에 각각의 모든 필드를 복제해야한다는 것입니다.

해결법

  1. ==============================

    1.

    CREATE VIEW EmployeeHistory
    AS
    , FirstName, , DepartmentId
    
    SELECT EmployeeId, RevisionXML.value('(/employee/FirstName)[1]', 'varchar(50)') AS FirstName,
    
      RevisionXML.value('(/employee/LastName)[1]', 'varchar(100)') AS LastName,
    
      RevisionXML.value('(/employee/DepartmentId)[1]', 'integer') AS DepartmentId,
    
    FROM EmployeeHistories 
    
  2. ==============================

    2.나는 '누가 / 무엇 역사를 사용하는 것입니다'여기 물어 핵심 질문은 생각하십니까?

    나는 '누가 / 무엇 역사를 사용하는 것입니다'여기 물어 핵심 질문은 생각하십니까?

    가 / 사람이 읽을 수있는 역사를보고 대부분이 될 것, 우리는 과거에이 방식을 구현했습니다 ...

    다음 필드가있는 'AuditTrail'라는 테이블이나 뭔가를 만들기 ...

    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NULL,
    [EventDate] [datetime] NOT NULL,
    [TableName] [varchar](50) NOT NULL,
    [RecordID] [varchar](20) NOT NULL,
    [FieldName] [varchar](50) NULL,
    [OldValue] [varchar](5000) NULL,
    [NewValue] [varchar](5000) NULL
    

    그런 다음 테이블에 갱신 / 삽입을 할 때마다 설정해야하는 귀하의 모든 테이블에 'LastUpdatedByUserID'열을 추가 할 수 있습니다.

    그런 다음이 발생하고 변경된 각 필드에 대해이 테이블에 항목을 만듭니다 어떤 삽입 / 업데이트를 잡기 위해 모든 테이블에 트리거를 추가 할 수 있습니다. 테이블도 각 업데이트 / 삽입에 대한 'LastUpdateByUserID'로 공급되고 있기 때문에, 당신은 트리거에서이 값에 액세스 할 수 있으며 감사 테이블에 추가 할 때 사용.

    우리는 테이블의 키 필드의 값이 업데이트되고 저장하는 recordID와 필드를 사용합니다. 이 결합 된 키가 있다면, 우리는 단지 필드 사이에있는 문자열 연결 '을 ~'할.

    나는 확실히이 시스템은 단점이있을 수 있습니다 해요 - 많이 업데이트 된 데이터베이스의 성능이 타격을받을 수 있지만, 내 웹 응용 프로그램을 위해, 우리는 많은 더 쓰기보다 읽기 얻고 그것은 꽤 잘 수행 할 것으로 보인다. 우리는 심지어 자동으로 테이블 정의를 기반으로 트리거를 작성하는 작은 VB.NET 유틸리티를 썼다.

    그냥 생각!

  3. ==============================

    3.데이터베이스 프로그래머 블로그의 역사 테이블 문서는 유용 할 수 있습니다 - 포인트 중 일부는 여기에 제기 커버와 델타의 저장에 대해 설명합니다.

    데이터베이스 프로그래머 블로그의 역사 테이블 문서는 유용 할 수 있습니다 - 포인트 중 일부는 여기에 제기 커버와 델타의 저장에 대해 설명합니다.

    편집하다

    역사 테이블 에세이에서, 저자 (케네스 다운스), 최소 7 개 컬럼의 역사 테이블을 유지하는 것이 좋습니다 :

    열은 그 역사를 필요하지 않습니다, 피하기 팽창에 기록 테이블에서 추적하지 말아야 변경되지 않거나 적이있다. 숫자 값 델타를 저장하는 것은 그것이 이전 및 새 값에서 파생 될 수 있지만, 이후의 쿼리를 쉽게 만들 수 있습니다.

    비 시스템 사용자가 삽입, 업데이트 또는 행 삭제 방지와 역사 테이블은 안전해야합니다. 만주기적인 정화는 전체 크기를 줄이기 위해 지원 (및 유스 케이스에서 허용하는 경우)해야한다.

  4. ==============================

    4.디자인 일을 피; 자동 또는 "수동"관리자 콘솔을 사용하여 - 당신은 기록의 이전 버전에 대한 예를 들어, 롤백에 필요하면 매우 편리하지 않습니다.

    디자인 일을 피; 자동 또는 "수동"관리자 콘솔을 사용하여 - 당신은 기록의 이전 버전에 대한 예를 들어, 롤백에 필요하면 매우 편리하지 않습니다.

    정말 디자인 2의 단점은 내가 두 번째는, 역사 테이블의 모든 열이 첫 번째, 기록 테이블에 제시 포함해야한다고 생각 표시되지 않습니다. 예를 들면 MySQL의에서 당신은 쉽게 다른 테이블과 동일한 구조 (Y와 같은 테이블 X를 생성)로 테이블을 만들 수 있습니다. 당신이 당신의 라이브 데이터베이스의 기록 테이블의 변화를 구조하려고했을 때, 당신은 어쨌든 테이블 변경 명령을 사용하는 - 그리고 당신의 역사 테이블에 대해 이러한 명령을 실행에 더 많은 노력이 없다.

    노트

    디자인 2의 작업은 매우 사소한 있습니다 :

    당신이 디자인이 갈 경우, 모든 SQL 명령은 유지 보수뿐만 아니라, 이들은 매우 매우 쉬운 것입니다 할 필요가! (고유 키 제외) 정확히 동일한 구조에서 두 테이블을 유지하기 위해 - 당신은 또한 기록 테이블의 보조 열 (수정 ID, DateModified)를 사용하는 경우 아마, 훨씬 더 쉽게 될 것입니다! 이것은 어떤 데이터 구조 변화에 내성이 될 것입니다 간단한 SQL 명령, 허용됩니다 :

    insert into EmployeeHistory select * from Employe where ID = XX
    

    사용 거래에 잊지 마세요!

    매우 간단한 쿼리 인덱스를 사용하여 - - 당신이 앞으로 XML의 뒷면에서 모든 데이터를 변환 단지 전체 테이블 행을 복사하지 않기 때문에 스케일링에 관해서는,이 솔루션은 매우 효율적이며 매우 효율적!

  5. ==============================

    5.우리는 크리스 로버츠가 제안하는 솔루션과 매우 유사한 솔루션을 구현 한, 그것은 우리를 위해 꽤 잘 작동합니다.

    우리는 크리스 로버츠가 제안하는 솔루션과 매우 유사한 솔루션을 구현 한, 그것은 우리를 위해 꽤 잘 작동합니다.

    유일한 차이점은 우리는 새로운 값을 저장한다는 것입니다. 오래된 값은 이전의 모든 기록 행에 저장 한 후

    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NULL,
    [EventDate] [datetime] NOT NULL,
    [TableName] [varchar](50) NOT NULL,
    [RecordID] [varchar](20) NOT NULL,
    [FieldName] [varchar](50) NULL,
    [NewValue] [varchar](5000) NULL
    

    당신이 20 열이있는 테이블이 있다고 할 수 있습니다. 이 방법은 당신은 단지 전체 행을 저장하는 대신 변경된 정확한 열을 저장해야합니다.

  6. ==============================

    6.당신이 가게의 역사에있는 경우 추적하는 테이블과 '개정일'과 '개정 유형'항목 (예를 들어, '삭제', '갱신')와 같은 스키마 그림자 테이블을 확인합니다. 쓰기 (또는 생성 - 아래 참조) 감사 테이블을 채우는 일련의 트리거.

    당신이 가게의 역사에있는 경우 추적하는 테이블과 '개정일'과 '개정 유형'항목 (예를 들어, '삭제', '갱신')와 같은 스키마 그림자 테이블을 확인합니다. 쓰기 (또는 생성 - 아래 참조) 감사 테이블을 채우는 일련의 트리거.

    그것은 테이블에 대한 시스템 데이터 사전을 읽고 그림자 테이블을 채우는 트리거 세트를 생성하는 스크립트를 생성하는 도구를 만들기 위해 매우 간단합니다.

    이를 위해 XML을 사용하지 마십시오, XML 스토리지는 기본 데이터베이스 테이블 스토리지보다 훨씬 덜 효율적이다 트리거 사용이 유형의 그.

  7. ==============================

    7.라 메쉬, 나는 첫 번째 방법에 따라 시스템의 개발에 참여했다. 그것은 XML로 개정을 저장하는 거대한 데이터베이스 증가로 이어지는 크게 일을 둔화되는 것을 밝혀졌다. 나의 접근 방식은 기업 당 하나 개의 테이블을 가지고하는 것입니다 :

    라 메쉬, 나는 첫 번째 방법에 따라 시스템의 개발에 참여했다. 그것은 XML로 개정을 저장하는 거대한 데이터베이스 증가로 이어지는 크게 일을 둔화되는 것을 밝혀졌다. 나의 접근 방식은 기업 당 하나 개의 테이블을 가지고하는 것입니다 :

    Employee (Id, Name, ... , IsActive)  
    

    곳이 isActive는 최신 버전의 표시이다

    당신이 개정 몇 가지 추가 정보를 연결하려는 경우 별도의 테이블을 만들 수 있습니다 그 정보를 포함하고 PK \ FK 관계를 사용하여 엔티티 테이블에 연결합니다.

    이 방법 당신은 하나 개의 테이블에서 직원의 모든 버전을 저장할 수 있습니다. 이 방법의 장점 :

    당신은 기본 키가 아닌 고유 할 수 있도록해야합니다.

  8. ==============================

    8.나는이 과거에 본 적이 있다는 방법이있다

    나는이 과거에 본 적이 있다는 방법이있다

    Employees (EmployeeId, DateModified, < Employee Fields > , boolean isCurrent );
    

    이 테이블에 당신은 결코 "업데이트"단지 새 행 삽입 (대해 IsCurrent의 유효을 변경 제외). 주어진 직원 ID를 들어, 단 1 행에 대해 IsCurrent == 1을 가질 수 있습니다.

    이 유지 관리의 복잡성은 (오라클에서, 나는 비슷한 일 다른 RDBMS를 가정), 당신도 갈 수에이 테이블이 너무 큰 인덱스에 의해 처리 할 수없는 경우 구체화 된 뷰를) 트리거 "대신"전망으로 숨겨져 될 수있다 .

    이 방법은 괜찮습니다,하지만 당신은 몇 가지 복잡한 쿼리로 끝날 수 있습니다.

    개인적으로, 나는뿐만 아니라 과거에 한 적이 어떻게 그 일을 당신의 디자인이 방법의 꽤 좋아입니다. 그것의 간단한 유지하기 위해 구현하는 간단하고 단순한을 이해합니다.

    그것은 또한 당신이 시간의 99 %를하고있을 것입니다 무엇을 가능성이있는, 읽기 쿼리를 수행 특히, 데이터베이스 및 응용 프로그램에 대한 약간의 오버 헤드를 생성합니다.

    또한 역사 테이블과 트리거의 생성이 (가 트리거를 통해 수행 할 것입니다 가정)을 유지하기 위해 자동 아주 쉬운 것입니다.

  9. ==============================

    9.데이터 개정 시간적 데이터베이스의 '유효 시간'의 일 측면이다. 많은 연구는이 들어갔, 많은 패턴과 가이드 라인이 등장했다. 내가 관심있는 사람들에게이 질문에 대한 참조의 무리와 함께 긴 답장을 썼다.

    데이터 개정 시간적 데이터베이스의 '유효 시간'의 일 측면이다. 많은 연구는이 들어갔, 많은 패턴과 가이드 라인이 등장했다. 내가 관심있는 사람들에게이 질문에 대한 참조의 무리와 함께 긴 답장을 썼다.

  10. ==============================

    10.당신과 함께 공유 내 디자인을거야하고 각 엔티티 유형 당 하나 개의 테이블을 필요로한다는 점에서 그것은 당신의 두 가지 설계는 다릅니다. 여기 내이야, 데이터베이스 설계는 ERD 통해 설명하는 가장 좋은 방법을 발견 :

    당신과 함께 공유 내 디자인을거야하고 각 엔티티 유형 당 하나 개의 테이블을 필요로한다는 점에서 그것은 당신의 두 가지 설계는 다릅니다. 여기 내이야, 데이터베이스 설계는 ERD 통해 설명하는 가장 좋은 방법을 발견 :

    이 예에서 우리는 엔티티라는 이름의 직원이있다. 사용자 테이블은 사용자의 기록과 실체와 entity_revision 당신이 시스템에있을 것이라는 점을 모든 개체 유형에 대한 수정 기록을 보유 두 테이블입니다 보유하고 있습니다. 이 디자인은 어떻게 작동하는지 여기입니다 :

    ENTITY_ID 및 REVISION_ID의 두 필드

    시스템의 각 개체는 자신의 고유 한 개체 ID를해야합니다. 당신의 기업은 개정을 통해 갈 수도 있지만 ENTITY_ID은 동일하게 유지됩니다. 당신은 (외래 키로)를 직원 테이블에서이 개체 ID를 유지해야합니다. 또한 엔티티 테이블 (예를 들어, '직원')에서 엔티티의 유형을 저장해야합니다. 이제 REVISION_ID에 관해서는, 그 이름에서 볼 수 있듯이, 그것은 당신의 엔티티 수정을 추적. 나는이 찾을 수있는 가장 좋은 방법은 당신의 REVISION_ID로 employee_id입니다을 사용하는 것입니다. 이 방법 당신은 개체의 다른 유형에 대한 중복 개정 ID를해야합니다하지만이 나에게 어떤 치료를 (나는 당신의 사건에 대해 잘 모르겠어요)입니다. 메이크업의 유일한 중요한 점은 ENTITY_ID 및 REVISION_ID의 조합이 고유해야한다는 것입니다.

    개정의 상태를 표시 entity_revision 테이블 내에서 상태 필드도 있습니다. 그것은 세 가지 상태 중 하나 일 수 있습니다 : 최신은, 쓸모 또는 삭제 (개정 날짜에 의존하지 당신에게 쿼리를 높일 수있는 좋은 거래를하는 데 도움).

    REVISION_ID에 마지막 주, 나는 우리가 미래에 추가 할 수 있습니다하는 각 개체 유형에 대한 ALTER entity_revision 테이블에 싶지 않기 때문에 REVISION_ID하는 employee_id입니다을 연결하는 외래 키를 생성하지 않았다.

    삽입

    당신이 데이터베이스에 삽입 할 것을 각 직원의 경우도 기업과 entity_revision에 레코드를 추가합니다. 이 마지막 두 개의 레코드는 레코드가 데이터베이스에 삽입 된 누구에 의해 언제 추적하는 데 도움이됩니다.

    최신 정보

    기존 직원 레코드에 대한 각 업데이트는 두 개의 삽입, 직원 테이블에서 하나 entity_revision의 하나로서 구현 될 것입니다. 두 번째는 당신이 누구와 레코드가 업데이트되었습니다에 의해 알고하는 데 도움이 될 것입니다.

    삭제

    직원 삭제를 들어, 기록 삭제를 주장 entity_revision에 삽입 이루어집니다.

    이 디자인에서 볼 수 있듯이 데이터가 적 변경하거나 데이터베이스에서 제거하고 더 중요한 것은 각 개체 유형은 하나의 테이블이 필요합니다. 개인적으로 나는이 디자인이 정말 유연하고 쉽게 작업 찾을 수 있습니다. 요구 사항이 다를 수 있습니다 그러나 나는 당신에 대해 확실하지 않다.

    [최신 정보]

    새로운 MySQL의 버전에서 지원되는 파티션을 갖는, 내 디자인도 너무 최고의 공연 중 하나와 함께 제공 믿습니다. 하나는 파티션 entity_revision이 상태 필드를 사용하는 동안 입력 필드를 사용하여 엔티티 테이블을 분할 할 수 있습니다. 디자인 간단하고 깨끗하게 유지하면서 이것은 지금까지 SELECT 질의를 높일 것입니다.

  11. ==============================

    11.참으로 감사 추적은 당신이 필요로하는 모든 경우, I (예를 들어 다른 테이블에 중요한 열 비정규 사본, 사용자 이름 완료) 감사 테이블 솔루션으로 의지 할 것입니다. 쓰라린 경험을 하나의 감사 테이블이 도로 아래로 큰 병목 현상을 나타냅니다됨을 기억하십시오; 그것은 모든 감사 테이블에 대한 개별 감사 테이블을 만들기 위해 노력 아마 가치가있다.

    참으로 감사 추적은 당신이 필요로하는 모든 경우, I (예를 들어 다른 테이블에 중요한 열 비정규 사본, 사용자 이름 완료) 감사 테이블 솔루션으로 의지 할 것입니다. 쓰라린 경험을 하나의 감사 테이블이 도로 아래로 큰 병목 현상을 나타냅니다됨을 기억하십시오; 그것은 모든 감사 테이블에 대한 개별 감사 테이블을 만들기 위해 노력 아마 가치가있다.

    당신이 실제 역사 (및 / 또는 미래) 버전을 추적해야하는 경우, 표준 용액은 시작, 종료 및 기간 값의 조합을 사용하여 여러 행과 같은 개체를 추적하는 것입니다. 당신은 편리 현재 값을 액세스 할 수 있도록 뷰를 사용할 수 있습니다. 이것은 당신이 가지고 접근하는 경우, 당신은 문제가 실행할 수있는 버전 화 된 데이터 참조를 변경할 수 있지만 버전없는 데이터의 경우.

  12. ==============================

    12.첫 번째 일을하고 싶은 경우에 당신은 너무 Employees 테이블에 대한 XML을 사용할 수 있습니다. 이 항상 문제가되지 않도록 대부분의 최신 데이터베이스는 XML 필드에 조회 할 수 있습니다. 그리고 최신 버전 또는 이전 버전의 경우에 관계없이 액세스 직원 데이터 하나 개의 방법이 더 간단 수 있습니다.

    첫 번째 일을하고 싶은 경우에 당신은 너무 Employees 테이블에 대한 XML을 사용할 수 있습니다. 이 항상 문제가되지 않도록 대부분의 최신 데이터베이스는 XML 필드에 조회 할 수 있습니다. 그리고 최신 버전 또는 이전 버전의 경우에 관계없이 액세스 직원 데이터 하나 개의 방법이 더 간단 수 있습니다.

    그래도 두 번째 방법을 시도 할 것입니다. 당신은 DateModified 필드와 함께 한 직원 테이블을함으로써이 문제를 단순화 할 수 있습니다. 직원 ID + DateModified는 기본 키가 될 것입니다 그리고 당신은 행을 추가하여 새로운 버전을 저장할 수 있습니다. 이 방법은 이전 버전을 보관 및 아카이브에서 버전을 복원 너무 쉽습니다.

    이 작업을 수행하는 또 다른 방법은 단 Linstedt으로 datavault 모델이 될 수 있습니다. 나는이 모델을 사용하는 네덜란드 통계국에 대한 프로젝트를하고 그것은 아주 잘 작동합니다. 그러나 나는이 일 데이터베이스 사용에 하루의 유용 생각하지 않습니다. 당신은 비록 자신의 논문을 읽고 몇 가지 아이디어를 얻을 수 있습니다.

  13. ==============================

    13.방법에 대해 :

    방법에 대해 :

    방금 각 직원 ID에 대한 MAX (DateModified)를 선택 기본 키 (직원 ID, DateModified)을 확인하고 "현재"레코드 (들)을 얻을 수 있습니다. 대해 IsCurrent를 저장하는 것은 무엇보다도 때문 계산 될 수 있고, 둘째, 그것은 너무 쉽게 데이터가 동기화하려면위한 것입니다, 아주 나쁜 생각이다.

    또한 앱에서 작업하는 동안 목록을 최신 기록, 주로 것을 사용하는 것이보기를 할 수 있습니다. 이 방법에 대한 좋은 것)는 데이터의 중복이없는, 당신은 두 개의 서로 다른 장소에서 데이터를 수집 할 필요가 없습니다 (종업원의 현재, 그리고 EmployeesHistory에 보관) 등 역사 또는 롤백 모두를 얻을 수 있다는 것입니다 .

  14. ==============================

    14.당신은 당신이이 같은 구조의 것을 사용한다 (이유를보고) 기록 데이터를 의존하려는 경우 :

    당신은 당신이이 같은 구조의 것을 사용한다 (이유를보고) 기록 데이터를 의존하려는 경우 :

    // Holds Employee Entity
    "Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"
    
    // Holds the Employee revisions in rows.
    "EmployeeHistories (HistoryId, EmployeeId, DateModified, OldValue, NewValue, FieldName)"
    

    응용 프로그램 또는 글로벌 솔루션 :

    // Holds Employee Entity
    "Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"
    
    // Holds all entities revisions in rows.
    "EntityChanges (EntityName, EntityId, DateModified, OldValue, NewValue, FieldName)"
    

    그런 다음 하나의 개정에 대해 하나 개의 기록을 가지고, XML에 또한 당신의 개정을 절약 할 수 있습니다. 이 같은 모습이 될 것입니다 :

    // Holds Employee Entity
    "Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"
    
    // Holds all entities revisions in rows.
    "EntityChanges (EntityName, EntityId, DateModified, XMLChanges)"
    
  15. ==============================

    15.우리는 비슷한 요구 사항을 가지고 있었고, 우리가 발견 한 것은 종종 사용자가 방금 변경 한 것을보고, 반드시 변경 사항을 롤백하고 싶어했다있다.

    우리는 비슷한 요구 사항을 가지고 있었고, 우리가 발견 한 것은 종종 사용자가 방금 변경 한 것을보고, 반드시 변경 사항을 롤백하고 싶어했다있다.

    내가 사용 사례가 무엇인지 모르겠지만, 우리가했던 것은 생성하고 자동으로 외래 키 참조와 열거의 친숙한 이름을 포함하는 비즈니스 엔티티 변경으로 업데이트 감사 테이블이었다.

    사용자가 자신의 변경 사항을 저장 할 때마다 우리는, 기존의 객체를 다시 비교를 실행, 변경 사항을 기록하고, 엔티티 저장 (문제가있는 모든 경우에 단일 데이터베이스 트랜잭션 (transaction)로 실행된다).

    이것은 우리의 사용자를 위해 아주 잘 작동하는 것 같다 우리에게 우리의 사업체와 동일한 필드 완전히 별도의 감사 테이블을 갖는 두통을 절약 할 수 있습니다.

  16. ==============================

    16.당신은 시간이 지남에 따라 특정 단체에 대한 변경 사항을 추적 할 것 예를 들면, 사운드 ID (3) "밥", "123 메인 스트리트"이라면 다른 ID 3, "밥" "234 엘름 성"등, 본질적으로 모든 어드레스 나타내는 업데이트 기록 아웃 토하고 수있는 "밥"에서왔다 .

    당신은 시간이 지남에 따라 특정 단체에 대한 변경 사항을 추적 할 것 예를 들면, 사운드 ID (3) "밥", "123 메인 스트리트"이라면 다른 ID 3, "밥" "234 엘름 성"등, 본질적으로 모든 어드레스 나타내는 업데이트 기록 아웃 토하고 수있는 "밥"에서왔다 .

    이 작업을 수행하는 가장 좋은 방법은 각각의 기록에 "있는 현재의"필드 및 날짜 / 시간 테이블 (아마) 타임 스탬프 또는 FK하는 것입니다.

    삽입 다음은 "현재는"또한 이전의 "최신"설정 해제 기록 "전류"로 설정해야합니다. 쿼리는 당신이 모든 역사를 원하는하지 않는 한은 "현재는"지정해야합니다.

    거기가 매우 큰 테이블, 또는 개정의 많은 수의 예상이 경우에 더 비틀기가 있지만, 이것은 매우 표준 접근 방식입니다.

  17. from https://stackoverflow.com/questions/39281/database-design-for-revisions by cc-by-sa and MIT license