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 deleted
Flag 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 deleted
Flag 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.