デルタのコンセプトと混同していると思います。
フルロード(データセット全体)または変更のみ(デルタ)を受け取ります。
フルロードを処理する場合は、トランケート+挿入を行うことができます。そうすれば、新旧の行や削除を処理する必要がなくなります。これは、参照整合性制約などで実現可能ではないかもしれない
あなたがデルタを受け取った場合、各行は、通常1〜2のカテゴリーに入れられる:
- マッチングキー=
UPDATE
。同じデータを持つ行を無視するか、上書きすることができます。
- 一致キー=
INSERT
削除は特別です。存在しない行は、あなたに送信することはできません。したがって、どのように対処するかについて同意する必要があります。フルロードの場合は、受信したデータセットに存在しないすべてのローカル行を削除できます。
デルタの場合、削除マーカー(フラグ、日付)を含む行を送信することに同意することができます。次に、削除マーカー(上記の(1)によって自動的に処理されます)を使用して行を保持するか、DELETE
行を保持するかを決定することができます。遅かれ早かれ誰かが行の不足/悪いデータの品質を告発し、DELETE_DATEを自分の顔に投げ捨てるので、それを残しておくことをお勧めします。
MySQLの場合、INSERT ... ON DUPLICATE KEY UPDATEを使用して "upsert"機能を実装できます。
より具体的なヘルプが必要な場合は、詳細を入力する必要があります。
更新:
[OK]を、ここでの例です。あなたは、次のテーブル構造を持っていることを言う:
create table contracts(
contract_id int not null
,details1 varchar(20)
,details2 varchar(20)
,delete_date date
,primary key(contract_id)
);
あなたが更新された行を受け取るたび、あなたは同じ構造を持つ一時テーブルにそれらを挿入します。
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
+-------------+----------+----------+-------------+
以前にリンクした構文を使用すると、すべての新しい行を挿入できます。行がすでに存在するときは(重複して)、代わりに列を更新することを選択しました。 delete_dateは他のすべてと同様に通常のカラムなので、これは自動的に削除された行を処理することに注意してください。 「アップサート」の後
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 |
+-------------+----------+----------+-------------+
- この時点では、デルタテーブルを削除するかを選択できます(次のそれを再作成することを忘れないでください時間)
- または一部の領域を節約するために切り捨てることができます。 、いつか
alter table contracts_delta rename to contracts_delta_20110115;
おかげか、あなたは、個々のデルタを必要包み、実際のデルタ(テーブルの名前を変更)を保存することができます -
(あなたはそれがとにかく次のロードに空のを確認する必要があります)ロニス。私は主にデルタケースに対処する方法を知りたい:1)更新行の場合、mysqlは正確な値が変更されているかどうかについてはあまり正確ではないようだ。同じ値で行を更新しても、影響を受ける行番号はまだ1/2です。 2)削除された行については、もちろん、私は行を永久に削除しません。しかし、私はそれらをアーカイブテーブルに削除するか、削除されたフラグを同じテーブルに入れるのが良いかどうかはわかりません。 – WilliamLou
@ロンニス:特にレコードを削除するソリューションを探しています。あるプロジェクトでは、削除フラグを使用しています。しかし、列に固有の制約があり、その固有の制約に違反する新しいレコードを作成したい場合はどうでしょうか。その場合、データを完全に削除する方がよいでしょう。しかし、クライアントは削除についてどのように通知されますか?私はIDを保存し、削除されたレコードの日付を削除するための2番目のテーブルを作成することを想像することができます。特別なテーブルを持たないソリューションはより良いでしょう。助言がありますか? – Konsumierer