2009-04-06 2 views
18

응용 프로그램 사용자가 특정 시점에 데이터의 스냅 샷을 만들 수있는 기능을 지원하는 데이터베이스를 디자인하는 방법. 버전 제어와 비슷합니다.데이터의 특정 시점 "스냅 샷"에 대한 데이터베이스 설계가 필요합니까?

사용자가 과거로 돌아가서 데이터가 어떻게 보이는지 확인할 수 있습니다.

"스냅 샷 된"데이터가 복잡하고 여러 테이블의 조인을 포함한다고 가정합니다.

각 응용 프로그램 사용자에게 데이터를 스냅 샷하고 다시 돌아갈 수있는 방법을 찾고 있습니다. 전체 데이터베이스 스냅 샷은 내가 찾는 것이 아닙니다.

편집 : 답변 해 주셔서 감사합니다. 6NF 응답은 간략 함으로 인해 스냅 샷 데이터를 비정규 화하는 것과 마찬가지로 강력합니다.

설명 : 데이터웨어 하우징 관련 질문이 아니며 DB 백업 및 복원에 대한 질문도 아닙니다. 특정 시점에 관련 데이터의 특정 세트 상태를 캡처 할 수있는 스키마를 작성하는 방법에 대해 설명합니다. 스냅 샷은 응용 프로그램 사용자가 적합하다고 판단되면 생성됩니다. 사용자는 전체 DB, 그들이 관심있는 데이터 만 개체 스냅 샷을하지 않습니다.

+0

SQL Server 2005 또는 2008. 그러나이 유형의 문제에 대한 솔루션이 내장 된 다른 RDBMS가 있다면 그에 대해 듣고 싶습니다. Thx – saille

답변

9

우리는 우리가 스냅 샷 원하는 데이터를 포함 별도의 데이터베이스 테이블을 작성하여 한 번 이런 짓을하지만, 비정규, 즉 모든 기록은 없습니다 참조 수도 있고 수도 더 이상 존재하지 않는 아이디의를 이해하는 데 필요한 모든 데이터를 포함. 또한 각 행에 날짜를 추가했습니다.

그런 다음 영향을받은 모든 테이블에 대한 조인을 수행 한 특정 삽입 또는 업데이트에 대한 트리거를 생성하여 스냅 샷 테이블에 삽입했습니다.

이 방법을 사용하면 사용자의 데이터를 특정 시점으로 복원하는 내용을 작성하는 것이 쉽습니다.

당신은 테이블이있는 경우 :

사용자 :

id, firstname, lastname, department_id 

부서 :

id, name, departmenthead_id 

사용자 테이블의 스냅 샷은 다음과 같이 수 :

user_id, user_firstname, user_lastname, department_id, department_name, deparmenthead_id, deparmenthead_firstname, departmenthead_lastname, snapshot_date 

그리고 뭔가를 쿼리 이케

INSERT INTO usersnapshot 
SELECT user.id AS user_id, user.firstname AS user_firstname, user.lastname AS user_lastname, 
department.id AS department_id, department.name AS department_name 
departmenthead.id AS departmenthead_id, departmenthead.firstname AS departmenthead_firstname, departmenthead.lastname AS departmenthead_lastname, 
GETDATE() AS snapshot_date 
FROM user 
INNER JOIN department ON user.department_id = department.id 
INNER JOIN user departmenthead ON department.departmenthead_id = departmenthead.id 

이 스냅 샷의 각 행을 보장 부서 또는 부서 헤드는 그 동안 변경된 경우에도, 시간에 그 순간 마찬가지입니다.

0

오라클을 만들 수있는 능력 플래시백 기술을 보유를 가지고 오라클 10g 및 11g의 성능이 크게 향상되었으며 플래시백을 사용하도록 설정 한 경우 역사의 특정 시점에서 데이터베이스의 상태를 볼 수 있습니다.

확인이 문서 : Flashback Overview

0

당신은 당신의 데이터의 스냅 샷을 얻기 위해 당신의 RDBMS에 의해 생성 된 로그를 사용할 수 있습니다. 일반적으로 로그는 데이터베이스 복구를 제공하는 데 사용됩니다. 그러나 여러 RDBMS 인스턴스에 걸쳐 데이터를 복제하거나 데이터의 스냅 샷을 얻는 데에도 사용할 수 있습니다.

데이터 스냅 샷을 얻으려면 원하는 순간 이전에 생성 된 모든 로그를 고려하십시오. 그런 다음 해당 로그를 "재생"하여 데이터가 복원 된 실제 데이터베이스를 얻습니다.

로그를 액세스하고 "재생"하는 방법은 사용하는 구체적인 RDBMS 제품에 따라 다릅니다.

또 다른 가능성은 임시 데이터베이스를 사용하는 것입니다. 그들은 시간 측면이 내장되어 있고 "돌아가는 시간"을 허용합니다. 예를 들어 "Oracle Flashback Technology"를 찾으십시오. http://www.stanford.edu/dept/itss/docs/oracle/10g/appdev.101/b10795/adfns_fl.htm#ADFNS1008

17

이것은 쉽지 않습니다.

본질적으로 임시 데이터베이스 (Christopher Date가 6th Normal Form 또는 6NF라고 부르는 것)를 요구하고 있습니다.

6NF가 되려면 스키마는 5NF, 이어야하며 기본적으로 각 데이터에 대해 해당 값의 데이터가 적용될 수있는 시간 범위를 첨부해야합니다. 그런 다음 조인에서 조인은 고려되는 시간 범위 내에있는 행만 포함시켜야합니다.

임시 모델링은 어렵습니다. 이것은 6th 일반 형식의 주소이며 현재 RDBMS에서 제대로 지원되지 않습니다.

문제는 입도입니다. 여섯 번째 정규 형식 (내가 이해할 때)은 모든 비키 (키가 아닌 : 즉, 엔터티가 신원을 잃지 않고 변경할 수있는 모든 것)을 별도의 관계로 만들어 일시적 모델링을 지원합니다. 여기에 타임 스탬프 또는 시간 범위 또는 버전 번호를 추가합니다. 모든 것을 합치면 세분성 문제가 해결되지만 쿼리가 더 복잡하고 느려질 수도 있습니다. 또한 모든 키와 키가 아닌 속성을 알아 내야합니다. 이것은 큰 노력을하는 경향이 있습니다.

는 기본적으로, 사방이 관계를 가지고 ("테드 ID 789와 GM의 주권 소유") 한 번 추가 : 당신이 동시에 말할 수 있도록 "테드 ID 789 지금와 GM의 주권을 소유"를, "fred는 2000 년 2 월 3 일부터 어제까지 ID 789로 GM 주식 증서를 소유하고 있습니다." 분명히 이러한 관계는 다 대다 (many-to-many)이며 (ted는 이제 하나 이상의 인증서를 소유 할 수 있으며, 평생 동안 둘 이상을 소유 할 수 있으며 fred는 이전에 소유 한 인증서 잭을 소유 할 수 있습니다).

그래서 우리는 소유주의 테이블과 주식 인증서 테이블, id로 소유자와 인증서를 관련시키는 many-to-many 테이블을 가지고 있습니다. many-to-many 테이블에 start_date와 end_date를 추가합니다.

이제 각 주 /도/토지가 주식 증서의 배당액에 세금을 부과하여 과세 목적으로 주식 증빙의 소유자의 주거 상태를 기록한다고 가정 해보십시오.

소유자가 거주하는 곳은 분명히 주식 소유권과 독립적으로 변경할 수 있습니다. 테드는 네브래스카에 살고 10 주를 살 수 있고 네브래스카가 세금을 부과하고 네바다로 이주하며 프레드에게 5 주를 팔고 10 주 더 살 수 있습니다.

그러나 우리를 위해, 그것은 테드는 약간의 시간이에 네브래스카 로 이동 시간이에 십주에게 를 살 수있어, 시간이, 네브라스카 세금에 배당 을받을 시간이에 Neveda 로 이동 어떤 시간에 fred 에 5 주를 팔고,에 더 많은 주식을 살 수 있습니다.

네브래스카와 네바다에서 세금 세금을 계산하고 person_stockcertificate 및 person_address의 일치/겹침 기간에 합류하기를 원한다면이 모든 것이 필요합니다. 주소가 인 동안 주소가 이기 때문에 사람의 주소는 더 이상 일대일이 아닙니다. 일대 다 주소입니다.

ted가 10 개의 주식을 사는 경우, 하나의 구매 날짜로 구매 이벤트를 모델링합니까, 아니면 각 주식에 date_bought를 추가합니까? 질문에 따라 답할 모델이 필요합니다.

+1

제네릭 솔루션은 확실히 성취하기가 어렵지만, 데이터 사용에 대한 구체적인 사용 사례와 하위 집합에 대해서는 설명 된 솔루션을 사용할 수 있습니다. –

0

적어도 SQL Server를 사용하면 전체 로깅을 사용하고 각 백업 세트간에 트랜잭션 로그를 유지할 수 있습니다.

그런 다음 특정 시점 백업을 수행 할 수 있습니다.

해결 방법이 좋지 않습니다.

고객이 정확히 원하는 것은 무엇입니까? 분석 목적을위한 것입니까? 예 : 2 주 전에 주문을 한 횟수는 몇 번입니까? 그것이 바로 데이터웨어 하우스가 해결하는 문제이기 때문입니다.

1

스냅 샷 및/또는 감사 추적 기능은 일반적인 데이터베이스 요구 사항입니다. 많은 응용 프로그램에서 '그림자'또는 감사 테이블을 만드는 것이 쉽고 직선적 인 작업입니다. 데이터베이스 수준의 백업 및 트랜잭션 로그가 있으면 좋지만 버전 제어 시스템은 아닙니다.

기본적으로 기본 테이블과 동일한 열이있는 섀도 테이블을 만든 다음 기본 테이블에서 트리거를 설정하여 섀도우 테이블이 업데이트되거나 삭제 될 때 섀도우 테이블에 복사본을 배치해야합니다.

일부 논리를 통해 특정 시점에서 데이터가 어떻게 보이는지 다시 만들 수 있습니다. Sybase에서이를 쉽게 설정할 수있는 방법은 다음과 같습니다. http://www.theeggeadventure.com/wikimedia/index.php/Sybase_Tips#create_.27audit.27_columns

많은 기록 스냅 샷을 수행해야하는 경우 동일한 테이블에 데이터를 보관할 수 있습니다. 기본적으로 두 개의 열, 즉 추가 및 삭제 된 열을 만듭니다. 단점은 모든 쿼리에 where 절을 추가해야한다는 것입니다. 물론 활성 레코드 만 보여주는 뷰를 생성 할 수 있습니다. 이것은 여러 개의 테이블이있는 정규화 된 데이터베이스를 모두 갖고 있다면 역사가 더 복잡해집니다.

그러나 작동합니다. 각 테이블에 '추가 된'열과 '삭제 된'열이있는 경우 쿼리에 관심있는 시점이 있습니다. 데이터가 수정 될 때마다 현재 행을 복사하여 삭제 된 것으로 표시해야합니다.

1

사용 Log Triggers

어느 시점에서 것처럼 조회 할 수있는 기능을 제공하는 변경 사항이 캡처 된 모든 데이터는.

0

MongoDB와 같은 NoSql 솔루션을 사용하여 모든 관계형 데이터를 단일 문서로 집계 한 다음 해당 문서를 타임 스탬프 또는 버전 번호와 함께 저장하는 것이 좋습니다. Kafka-Connect 또는 Oracle Golden Gate와 같은 솔루션은 관계형 데이터를 NoSql 스토어로 단순화합니다.

관련 문제