Tabella Tombstone vs Flag eliminato nella sincronizzazione del database e scenari di soft-delete


17

Devo tenere traccia degli elementi eliminati per le esigenze di sincronizzazione del client.

In generale, è meglio aggiungere una tabella tombstone e un trigger che tiene traccia di quando una riga è stata eliminata dal database del server - fondamentalmente aggiungendo una nuova riga alla tabella tombstone con i dati dall'elemento eliminato - o per mantenere gli elementi nel tabella originale e contrassegnarli come eliminati, in genere con una colonna di tipo bit, per indicare che una riga viene eliminata e un'altra colonna da tracciare quando si è verificata l'eliminazione?

Risposte:


17

In generale è meglio conoscere i requisiti specifici e non prendere decisioni di progettazione basate su ciò che funziona meglio nella maggior parte delle situazioni. O potrebbe essere preferibile. Ecco alcuni dettagli da raccogliere:

  • Quanto devono essere veloci le eliminazioni?
  • Quanto devono essere veloci le cancellazioni?
  • Con quale frequenza verranno interrogati i dati eliminati e verranno interrogati con dati che non sono stati eliminati?
  • Quanto devono essere veloci le query sui dati eliminati?
  • Devi conservare solo gli elementi o le modifiche eliminati?
  • Devi mantenere piccola la tabella / gli indici sulla tabella primaria?
  • Quali tecnologie di partizionamento e / o modifica delle modifiche sono disponibili sulla piattaforma del database?
  • Quanto spazio su disco è disponibile?
  • La cancellazione avverrà al volo o in operazioni batch?

Vedo, è una questione di scambio tra diversi requisiti di sistema. Se avessi bisogno di cancellazioni / cancellazioni rapide, la bandiera sarebbe preferibile, ma se avessi bisogno di interrogazioni veloci su elementi eliminati e anche sulla tabella principale e forse dovessi tenere traccia di qualsiasi tipo di modifica, l'approccio lapide potrebbe essere meglio.
Lorenzo Polidori,

Avete capito bene. Potrebbero anche esserci casi in cui sarebbe preferibile un'altra opzione. Ad esempio, se hai solo bisogno che le eliminazioni automatiche siano disponibili per 24 ore, in Oracle potresti considerare di impostare un tempo di conservazione degli annullamenti garantiti e quindi utilizzare le query di flashback per vedere i dati eliminati.
Leigh Riffel,

5

Forse dovresti combinare i due metodi apposta. Perché ???

Usiamo quella tabella (dialetto MySQL)

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)
);

Si noti che, ad eccezione del PRIMARY KEY, ogni indice creato deve essere preceduto dalla deletedbandiera e terminare con il simbolo id.

Creiamo la tabella della lapide

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

Se la tua tabella ha già una deletedbandiera, potresti popolare la tabella di pietra preziosa

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

OK ora i dati e la lapide sono preparati. Come si eseguono le eliminazioni?

Supponiamo che tu stia eliminando tutte le persone nel codice postale 07305. Dovresti eseguire quanto segue:

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, questo sembra un sacco di spese generali in entrambi i modi.

Ora, vuoi vedere tutti i dati cancellati? Ecco due modi diversi:

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

Se il numero di ID in mytomb è superiore al 5% del conteggio delle righe di mydata, si tratta della scansione della tabella completa. Altrimenti, una scansione dell'indice con una ricerca per ogni riga. Nota eventuali parametri di riferimento in questi aspetti. Cerca i piani di spiegazione.

Ora, vuoi vedere tutte le persone nel codice postale 07304? Ecco due modi diversi:

  • 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'

Che ne dici di cancellazioni di massa? Ecco due modi diversi:

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

CONCLUSIONE

Ora, non sto dicendo di mantenere entrambi i metodi. In questo modo nel tempo si rivela quale metodo è più veloce in termini di operabilità complessiva. È necessario decidere quali parametri di riferimento per l'interrogazione di dati in tempo reale, l'interrogazione di dati eliminati e le eliminazioni di massa funzionano meglio per l'utente.


C'è un vantaggio nell'usare entrambe le tecniche, su base continuativa? O stai suggerendo di usarli in parallelo per valutare le prestazioni e poi impegnarti con l'uno o l'altro?
Jon of All Trades,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.