델타 개념과 혼동 스럽다고 생각합니다.
전체로드 (전체 데이터 세트) 또는 변경 사항 ("델타") 만받습니다.
전체로드를 처리하는 경우 잘라내 기 + 삽입을 수행 할 수 있습니다. 그렇게하면 새로운 행과 오래된 행 또는 삭제를 처리 할 필요가 없습니다. 이는 참조 무결성 제한 조건 등으로 가능하지 않을 수 있습니다
당신은 델타를받은 경우, 각 행은 일반적으로 1 2의 범주에 넣고 :
- 매칭 키 =
UPDATE
. 동일한 데이터를 가진 행을 무시하거나 덮어 쓸 수 있습니다.
- 일치하는 키 =
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;
감사를 개별 델타를 필요 넣다 당신이 실제 델타을 저장 (테이블의 이름을 변경) 할 수 있습니다, 로니 스. 나는 주로 델타 케이스를 다루는 방법을 알고 싶다 : 1) 업데이트 행에 대해, mysql은 정확한 값의 변경 여부에 대해 그렇게 정확하지는 않다. 동일한 값으로 행을 업데이트하더라도 영향을받는 행 번호는 여전히 1/2입니다. 2) 삭제 된 행에 대해서는 물론 행을 영구적으로 삭제하지 않습니다. 그러나, 나는 그것들을 아카이브 테이블로 제거하거나 삭제 된 플래그를 같은 테이블에 두는 것이 더 나은지 잘 모르겠습니다. – WilliamLou
@Ronnis : 특히 레코드 삭제를위한 솔루션을 찾고 있습니다. 한 프로젝트에서 우리는 삭제 플래그를 사용하고 있습니다. 하지만 열에 고유 한 제한 조건이 있고 고유 제한 조건을 위반하는 새 레코드를 작성하려는 경우에는 어떻게해야합니까? 이 경우 데이터를 완전히 삭제하는 것이 좋습니다. 그러나 클라이언트가 삭제에 대해 어떻게 알 수 있습니까? 나는 ID를 저장하고 삭제 된 레코드의 날짜를 삭제하는 두 번째 테이블을 만드는 것을 상상할 수 있습니다. 추가 테이블이없는 솔루션이 더 좋을 것입니다. 어떤 제안? – Konsumierer