Tombstone Table vs Deleted Flag dans les scénarios de synchronisation de base de données et de suppression logicielle

17

Je dois garder une trace des éléments supprimés pour les besoins de synchronisation du client.

En général, est-il préférable d'ajouter une table tombstone et un déclencheur qui suit quand une ligne a été supprimée de la base de données du serveur - en gros, ajouter une nouvelle ligne à la table tombstone avec les données de l'élément supprimé - ou de conserver les éléments dans le table d'origine et les marquer comme supprimés, généralement avec une colonne de type bit, pour indiquer qu'une ligne est supprimée et une autre colonne pour suivre quand la suppression s'est produite?

Lorenzo Polidori
la source

Réponses:

17

En général, il est préférable de connaître les exigences spécifiques et de ne pas prendre de décisions de conception en fonction de ce qui fonctionne le mieux dans la plupart des situations. Soit pourrait être préférable. Voici quelques détails à recueillir:

  • À quelle vitesse les suppressions doivent-elles être effectuées?
  • Quelle doit être la rapidité des suppressions?
  • À quelle fréquence les données supprimées seront-elles interrogées et seront-elles interrogées avec des données qui n'ont pas été supprimées?
  • Quelle doit être la rapidité des requêtes de données supprimées?
  • Devez-vous également conserver uniquement les éléments supprimés ou les modifications?
  • Devez-vous garder la table / les index de la table principale petits?
  • Quelles technologies de partitionnement et / ou de suivi des modifications sont disponibles sur la plateforme de base de données?
  • Combien d'espace disque est disponible?
  • La suppression aura-t-elle lieu à la volée ou lors d'opérations par lots?
Leigh Riffel
la source
Je vois, c'est une question de compromis entre les différentes exigences du système. Si j'ai besoin de suppressions / suppressions rapides, le drapeau serait préférable, mais si j'ai besoin de requêtes rapides sur les éléments supprimés et sur la table principale et peut-être que je dois garder une trace de tout type de changements, l'approche de pierre tombale pourrait être mieux.
Lorenzo Polidori
Tu l'as eu. Il pourrait même y avoir des cas où une autre option serait préférable. Par exemple, si vous avez uniquement besoin que les suppressions logicielles soient disponibles pendant 24 heures, dans Oracle, vous pouvez envisager de définir un temps de rétention d'annulation garanti, puis d'utiliser des requêtes flashback pour voir les données supprimées.
Leigh Riffel
5

Vous devriez peut-être combiner exprès les deux méthodes. Pourquoi ???

Utilisons cette table (MySQL-dialect)

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

Veuillez noter qu'à l'exception de la CLÉ PRIMAIRE, chaque index que vous créez doit être précédé du deleteddrapeau et se terminant par le id.

Créons la table tombstone

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

Si votre table a déjà un deletedindicateur, vous pouvez remplir la table tommstone

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

OK maintenant les données et la pierre tombale sont préparées. Comment effectuez-vous des suppressions?

Supposons que vous supprimiez chaque personne du code postal 07305. Vous exécuteriez ce qui suit:

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, cela semble être beaucoup de frais généraux de toute façon que vous le regardez.

Maintenant, voulez-vous voir toutes les données supprimées? Voici deux façons différentes:

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

Si le nombre d'identifiants dans mytomb est supérieur à 5% du nombre de lignes de mydata, il s'agit d'une analyse complète de la table. Sinon, une analyse d'index avec une recherche pour chaque ligne. Notez tous les repères à ces égards. Recherchez les plans d'explication.

Maintenant, voulez-vous voir chaque personne dans le code postal 07304? Voici deux façons différentes:

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

Qu'en est-il des suppressions massives? Voici deux façons différentes:

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

CONCLUSION

Maintenant, je ne dis pas de garder les deux méthodes. Faire cela au fil du temps révèle quelle méthode est la plus rapide en termes d'opérabilité globale. Vous devez décider quels repères pour interroger des données en direct, interroger des données supprimées et des suppressions massives vous conviennent le mieux.

RolandoMySQLDBA
la source
Y a-t-il un avantage à utiliser les deux techniques de façon continue? Ou proposez-vous simplement de les utiliser en parallèle pour évaluer les performances, puis de vous engager dans l'un ou l'autre?
Jon of All Trades