Ich denke, Sie sind mit dem Konzept eines Deltas verwechselt.
Entweder Sie erhalten volle Lasten (der gesamte Datensatz) oder nur die Änderungen (das "Delta").
Wenn Sie mit vollen Lasten arbeiten, können Sie einen trunkate + einfügen. Auf diese Weise müssen Sie nicht mit neuen oder alten Zeilen oder Löschungen umgehen. Dies kann nicht möglich sein, weil die referenziellen Integrität usw.
Wenn Sie ein Delta erhalten, wird jede Zeile der Regel in 1 von 2 Gruppen unterteilt:
- Matching key =
UPDATE
. Sie können festlegen, dass Zeilen mit identischen Daten ignoriert oder überschrieben werden.
- keine passenden Schlüssel =
INSERT
Deletes ist etwas Besonderes. Zeilen, die nicht existieren, können nicht an Sie gesendet werden. Daher müssen Sie sich darauf einigen, wie Sie damit umgehen sollen. Bei voller Auslastung können Sie alle lokalen Zeilen löschen, die im empfangenen Datensatz nicht vorhanden sind.
Im Fall von Delta können Sie zustimmen, die Zeile mit einem Löschmarker (Flag, Datum) zu senden. Sie können dann entscheiden, ob Sie die Zeile mit einem Löschmarker (automatisch von (1) oben behandelt) beibehalten möchten, oder ob Sie Ihre Zeile DELETE
sollten. Ich schlage vor, es zu behalten, denn früher oder später wird Ihnen jemand fehlende Zeilen/schlechte Datenqualität vorwerfen und dann werfen Sie das DELETE_DATE in ihr Gesicht.
Für MySQL können Sie verwenden, um "upsert" -Funktionalität zu implementieren.
Sie müssten mehr Details angeben, wenn Sie spezifischere Hilfe benötigen.
Update:
Ok, hier ist ein Beispiel.Sagen Sie, dass Sie die folgende Tabellenstruktur haben:
create table contracts(
contract_id int not null
,details1 varchar(20)
,details2 varchar(20)
,delete_date date
,primary key(contract_id)
);
Jedes Mal, wenn Sie die aktualisierten Zeilen erhalten, können Sie sie in eine temporäre Tabelle mit identischer Struktur einfügen:
create table contracts_delta(
contract_id int not null
,details1 varchar(20)
,details2 varchar(20)
,delete_date date
,primary key(contract_id)
);
Einige Beispieldaten:
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
+-------------+----------+----------+-------------+
Mit der Syntax, mit der ich früher verbunden habe, können Sie alle neuen Zeilen einfügen. Immer wenn die Zeile bereits vorhanden ist (doppelt vorhanden), haben wir uns dafür entschieden, die Spalten zu aktualisieren. Beachten Sie, dass gelöschte Zeilen automatisch behandelt werden, da delete_date eine reguläre Spalte wie alles andere ist.
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;
Nach dem „Upsert“ werden die Daten in den Verträgen werden wie folgt aussehen:
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 |
+-------------+----------+----------+-------------+
- An dieser Stelle können Sie wählen die Delta-Tabelle löschen (nicht vergessen, es neben neu zu erstellen Zeit)
drop table contracts_delta;
- Oder man kann es nur gestutzt, um Platz zu sparen. (Sie müssen sicherstellen, dass es auf der nächsten Ladung sowieso leer ist)
truncate table contracts_delta;
- Oder können Sie das aktuelle Delta speichern (benennen Sie die Tabelle) einhüllen Sie die einzelne Deltas müssen irgendwann
alter table contracts_delta rename to contracts_delta_20110115;
Dank, Ronnis. Ich möchte hauptsächlich wissen, wie man mit delta case umgeht: 1) Für Update-Zeilen scheint mysql nicht so genau zu sein, ob sich der genaue Wert ändert oder nicht. Selbst wenn Sie die Zeile mit denselben Werten aktualisieren, ist die betroffene Zeilennummer immer noch 1/2; 2) für gelöschte Zeilen werde ich natürlich die Zeilen nicht dauerhaft löschen. Ich bin mir jedoch nicht sicher, ob es besser ist, sie in eine Archivtabelle zu kopieren oder ein gelöschtes Flag in dieselbe Tabelle zu setzen. – WilliamLou
@Ronnis: Ich suche vor allem nach einer Lösung zum Löschen von Datensätzen. In einem Projekt verwenden wir eine Löschflagge. Was aber, wenn Sie eine eindeutige Einschränkung für eine Spalte haben und einen neuen Datensatz erstellen möchten, der gegen die eindeutige Einschränkung verstößt? Es wäre definitiv besser, die Daten in diesem Fall vollständig zu löschen. Aber wie werden die Kunden über die Löschung informiert? Ich könnte mir vorstellen, eine zweite Tabelle zu erstellen, um die IDs zu speichern und das Datum der gelöschten Datensätze zu löschen. Eine Lösung ohne zusätzliche Tabelle wäre schöner. Irgendwelche Vorschläge? – Konsumierer