Tombstone-Tabelle gegen gelöschtes Flag in Szenarien mit Datenbanksynchronisierung und Soft-Delete


17

Ich muss gelöschte Elemente für die Client-Synchronisierungsanforderungen nachverfolgen.

Im Allgemeinen ist es besser, eine Tombstone-Tabelle und einen Auslöser hinzuzufügen , der nachverfolgt, wann eine Zeile aus der Serverdatenbank gelöscht wurde - im Grunde genommen, wenn der Tombstone-Tabelle eine neue Zeile mit den Daten aus dem gelöschten Element hinzugefügt wird - oder die Elemente in der Liste beizubehalten Originaltabelle und kennzeichnen sie als gelöscht, normalerweise mit einer Spalte vom Typ Bit, um anzuzeigen, dass eine Zeile gelöscht wurde und eine andere Spalte, um zu verfolgen, wann der Löschvorgang stattgefunden hat?

Antworten:


17

Im Allgemeinen ist es besser, die spezifischen Anforderungen zu kennen und keine Entwurfsentscheidungen zu treffen, die auf dem basieren, was in den meisten Situationen am besten funktioniert. Beides könnte vorzuziehen sein. Hier sind einige Details zu sammeln:

  • Wie schnell müssen Löschvorgänge sein?
  • Wie schnell müssen Löschvorgänge sein?
  • Wie oft werden gelöschte Daten abgefragt und werden sie mit nicht gelöschten Daten abgefragt?
  • Wie schnell müssen Abfragen von gelöschten Daten sein?
  • Müssen Sie auch nur gelöschte Elemente oder Änderungen beibehalten?
  • Müssen Sie die Tabelle / Indizes auf der Primärtabelle klein halten?
  • Welche Partitionierungs- und / oder Änderungsverfolgungstechnologien sind auf der Datenbankplattform verfügbar?
  • Wie viel Speicherplatz ist verfügbar?
  • Erfolgt das Löschen im laufenden Betrieb oder im Stapelbetrieb?

Ich verstehe, es geht darum, zwischen verschiedenen Systemanforderungen abzuwägen. Wenn ich schnelle Löschvorgänge / Löschvorgänge aufheben möchte, ist das Flag vorzuziehen. Wenn ich jedoch schnelle Abfragen zu gelöschten Elementen und zur Primärtabelle benötige und möglicherweise Änderungen nachverfolgen muss, ist der Tombstone-Ansatz möglicherweise der richtige besser.
Lorenzo Polidori

Du hast es. Es könnte sogar Fälle geben, in denen eine andere Option vorzuziehen wäre. Wenn Sie zum Beispiel nur benötigen, dass die vorläufigen Löschvorgänge 24 Stunden lang verfügbar sind, können Sie in Oracle eine garantierte Aufbewahrungszeit für das Rückgängigmachen festlegen und dann Flashback-Abfragen verwenden, um gelöschte Daten anzuzeigen.
Leigh Riffel

5

Vielleicht sollten Sie die beiden Methoden absichtlich kombinieren. Warum ???

Verwenden wir diese Tabelle (MySQL-Dialekt)

CREATE TABLE mydata
(
    id int not null auto_increment
    firstname varchar(16) not null,
    lastname varchar(16) not null,
    zipcode char(5) not null,
    ...
    deleted tinyint not null default 0
    KEY (deleted,id),
    KEY (deleted,lastname,firstname,id),
    KEY (deleted,zipcode,id),
    KEY (lastname,firstname),
    KEY (zipcode),
    PRIMARY KEY (id)
);

Bitte beachten Sie, dass mit Ausnahme des PRIMARY KEY jedem Index, den Sie erstellen, das deletedFlag vorangestellt werden muss und mit dem endet id.

Lassen Sie uns die Tombstone-Tabelle erstellen

CREATE TABLE mytomb SELECT id FROM mydata WHERE 1=2;
ALTER TABLE mytomb ADD PRIMARY KEY (id);

Wenn Ihre Tabelle bereits ein deletedFlag enthält, können Sie die Tommy-Stone-Tabelle füllen

INSERT INTO mytomb SELECT id FROM mydata WHERE deleted = 1;

OK, jetzt sind die Daten und der Tombstone vorbereitet. Wie führen Sie Löschvorgänge durch?

Angenommen, Sie löschen jede Person in der Postleitzahl 07305. Sie würden Folgendes ausführen:

INSERT IGNORE INTO mytomb SELECT id FROM mydata WHERE deleted=0 AND zipcode='07305';
UPDATE mydata SET deleted=1 WHERE deleted=0 AND zipcode='07305';

OK, das scheint so oder so viel Aufwand zu bedeuten.

Möchten Sie jetzt alle gelöschten Daten sehen? Hier sind zwei verschiedene Möglichkeiten:

  • SELECT * FROM mydata WHERE deleted=1;
  • SELECT B.* FROM mytomb A INNER JOIN mydata B USING (id);

Wenn die Anzahl der IDs in mytomb mehr als 5% der Zeilenanzahl von mydata beträgt, handelt es sich um einen vollständigen Tabellenscan. Andernfalls wird ein Index-Scan mit einer Suche für jede Zeile durchgeführt. Beachten Sie alle Benchmarks in dieser Hinsicht. Schauen Sie sich die EXPLAIN-Pläne an.

Möchten Sie jetzt jede Person in Postleitzahl 07304 sehen? Hier sind zwei verschiedene Möglichkeiten:

  • SELECT * FROM mydata WHERE deleted=1 AND zipcode='07304';
  • SELECT A.* FROM mydata A LEFT JOIN mytomb B USING (id) WHERE B.id IS NULL AND A.zipcode='07304'

Wie wäre es mit Massenlöschungen? Hier sind zwei verschiedene Möglichkeiten:

  • DELETE FROM mydata WHERE deleted=1;
  • DELETE B.* FROM mytomb A INNER JOIN mydata B USING (id); DELETE FROM mytomb;

FAZIT

Jetzt sage ich nicht, beide Methoden beizubehalten. Dies im Laufe der Zeit zu tun, zeigt, welche Methode in Bezug auf die allgemeine Bedienbarkeit schneller ist. Sie müssen entscheiden, welche Benchmarks für die Abfrage von Live-Daten, die Abfrage gelöschter Daten und die Massenlöschung am besten für Sie geeignet sind.


Gibt es einen Vorteil, wenn beide Techniken kontinuierlich angewendet werden? Oder schlagen Sie vor, sie nur parallel zu verwenden, um die Leistung zu bewerten, und sich dann auf die eine oder andere festzulegen?
Jon of All Trades
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.