2011-01-13 3 views
2

논의 용 질문입니다. 지금 당장은 mysql 데이터베이스 테이블을 다시 디자인해야합니다. 기본적으로이 테이블에는 다른 데이터베이스에서 동기화 한 모든 계약 레코드가 들어 있습니다. 계약 레코드를 수정하거나 삭제하거나 사용자가 GUI 인터페이스를 통해 새 계약 레코드를 추가 할 수 있습니다. 이 단계에서 테이블 구조는 계약 정보 (열 : 일련 번호, 만료 날짜 등)와 정확히 동일합니다. 이 경우 전체 테이블 만 동기화 할 수 있습니다 (이전 레코드를 모두 삭제하고 새 레코드로 대체). 델타 (수정 된 새 레코드, 삭제 된 레코드와 만 동기화) 테이블을 동기화하려면 데이터베이스 스키마를 어떻게 변경해야합니까?델타 동기화에 적합한 데이터베이스 스키마

여기 나와있는 방법이 있지만 데이터베이스 응용 프로그램의 일반적인 시나리오라고 생각하기 때문에 제안이 필요합니다. 1) 시퀀스 번호 개념/열 소개 : 각 시퀀스에 대해 새로 추가 된 레코드, 수정 된 레코드, 삭제 된 레코드를이 시퀀스 번호로 표시합니다. 마지막으로 동기화 된 시퀀스 번호를 기록하면 더 높은 시퀀스 번호를 가진 레코드 만 전달합니다.

2) 삭제 된 계약을 다시 추가 할 수 있고 원본 테이블에 기본 키 제약 조건이 있으므로 삭제 된 레코드에 대해 다른 테이블을 만들어야합니까? 이 계약서가 삭제되었는지 여부를 나타내는 플래그 열을 추가 하시겠습니까?

나는 내 질문을 명확하게 설명하기를 바랍니다. 어쨌든, 이에 대한 기사 나 제안 사항을 알고 있다면 알려주십시오. 감사!

답변

8

델타 개념과 혼동 스럽다고 생각합니다.

전체로드 (전체 데이터 세트) 또는 변경 사항 ("델타") 만받습니다.

전체로드를 처리하는 경우 잘라내 기 + 삽입을 수행 할 수 있습니다. 그렇게하면 새로운 행과 오래된 행 또는 삭제를 처리 할 필요가 없습니다. 이는 참조 무결성 제한 조건 등으로 가능하지 않을 수 있습니다

당신은 델타를받은 경우, 각 행은 일반적으로 1 2의 범주에 넣고 :

  1. 매칭 키 = UPDATE. 동일한 데이터를 가진 행을 무시하거나 덮어 쓸 수 있습니다.
  2. 일치하는 키 = INSERT

삭제는 특별하다. 존재하지 않는 행은 사용자에게 전송 될 수 없습니다. 따라서 어떻게 처리해야하는지에 동의해야합니다. 전체로드의 경우, 수신 된 데이터 세트에 존재하지 않는 모든 로컬 행을 삭제할 수 있습니다.

델타의 경우 삭제 표시 (플래그, 날짜)와 함께 행을 보내는 것에 동의 할 수 있습니다. 그런 다음 삭제 마커 (위의 (1)에 의해 자동으로 처리됨)로 행을 유지할지 또는 DELETE 행을 유지할지 결정할 수 있습니다. 조만간 누군가 누락 된 행/나쁜 데이터 품질에 대해 비난하고 DELETE_DATE를 자신의 얼굴에 던지기 때문에 보관하는 것이 좋습니다.

MySQL의 경우 INSERT ... ON DUPLICATE KEY UPDATE을 사용하여 "upsert"기능을 구현할 수 있습니다.

보다 구체적인 도움이 필요한 경우 자세한 내용을 제공해야합니다.

는 업데이트 :

좋아, 여기에 예입니다.다음과 같은 테이블 구조를 가지고 말 :

create table contracts_delta(
    contract_id int   not null 
    ,details1 varchar(20) 
    ,details2 varchar(20) 
    ,delete_date date 
    ,primary key(contract_id) 
); 

일부 예제 데이터 :

mysql> select * from contracts; 
+-------------+----------+----------+-------------+ 
| contract_id | details1 | details2 | delete_date | 
+-------------+----------+----------+-------------+ 
|   1 | a1  | a2  | NULL  | 
|   2 | b1  | b2  | NULL  | 
|   3 | c1  | c2  | 2011-01-03 | 
+-------------+----------+----------+-------------+ 

mysql> select * from contracts_delta; 
+-------------+----------+----------+-------------+ 
| contract_id | details1 | details2 | delete_date | 
+-------------+----------+----------+-------------+ 
|   2 | b1  | b2  | 2011-01-03 | <-- Row was deleted 
|   3 | c1  | c2  | NULL  | <-- No longer deleted 
|   4 | d1  | d2  | NULL  | <-- This is new row 
+-------------+----------+----------+-------------+ 
업데이트 된 행을받을 때마다

create table contracts(
    contract_id int   not null 
    ,details1 varchar(20) 
    ,details2 varchar(20) 
    ,delete_date date 
    ,primary key(contract_id) 
); 

을, 당신은 동일한 구조와 임시 테이블에 삽입

이전에 링크 된 구문을 사용하여 모든 새 행을 삽입 할 수 있습니다. 행이 이미 존재할 때마다 (복제시) 우리는 대신 열을 업데이트하기로 결정했습니다. delete_date는 다른 모든 것과 마찬가지로 일반 열이므로 삭제 된 행이 자동으로 처리됩니다. 은 "upsert", 계약의 데이터는 다음과 같이됩니다 후

insert 
    into contracts(
     contract_id 
     ,details1 
     ,details2 
     ,delete_date 
     ) 
select contract_id 
     ,details1 
     ,details2 
     ,delete_date 
    from contracts_delta s 
    on duplicate key 
    update contracts.details1 = s.details1 
      ,contracts.details2 = s.details2 
      ,contracts.delete_date = s.delete_date; 

:

mysql> select * from contracts; 
+-------------+----------+----------+-------------+ 
| contract_id | details1 | details2 | delete_date | 
+-------------+----------+----------+-------------+ 
|   1 | a1  | a2  | NULL  | 
|   2 | b1  | b2  | 2011-01-03 | 
|   3 | c1  | c2  | NULL  | 
|   4 | d1  | d2  | NULL  | 
+-------------+----------+----------+-------------+ 

-이 시점에서 델타 테이블을 삭제하도록 선택할 수 있습니다 (다음 그것을 다시 만들 기억 시간)

- 또는 일부 공간을 절약하기 위해자를 수 있습니다.

truncate table contracts_delta; 

(당신은 확실히 어쨌든 다음로드에 비어 만들 필요) - 또는 당신은 언젠가

alter table contracts_delta rename to contracts_delta_20110115; 
+0

감사를 개별 델타를 필요 넣다 당신이 실제 델타을 저장 (테이블의 이름을 변경) 할 수 있습니다, 로니 스. 나는 주로 델타 케이스를 다루는 방법을 알고 싶다 : 1) 업데이트 행에 대해, mysql은 정확한 값의 변경 여부에 대해 그렇게 정확하지는 않다. 동일한 값으로 행을 업데이트하더라도 영향을받는 행 번호는 여전히 1/2입니다. 2) 삭제 된 행에 대해서는 물론 행을 영구적으로 삭제하지 않습니다. 그러나, 나는 그것들을 아카이브 테이블로 제거하거나 삭제 된 플래그를 같은 테이블에 두는 것이 더 나은지 잘 모르겠습니다. – WilliamLou

+0

@Ronnis : 특히 레코드 삭제를위한 솔루션을 찾고 있습니다. 한 프로젝트에서 우리는 삭제 플래그를 사용하고 있습니다. 하지만 열에 고유 한 제한 조건이 있고 고유 제한 조건을 위반하는 새 레코드를 작성하려는 경우에는 어떻게해야합니까? 이 경우 데이터를 완전히 삭제하는 것이 좋습니다. 그러나 클라이언트가 삭제에 대해 어떻게 알 수 있습니까? 나는 ID를 저장하고 삭제 된 레코드의 날짜를 삭제하는 두 번째 테이블을 만드는 것을 상상할 수 있습니다. 추가 테이블이없는 솔루션이 더 좋을 것입니다. 어떤 제안? – Konsumierer