2009-08-27 5 views
1

J'ai 8 tables:Comment archiver un enregistrement avec des enregistrements d'autres tables connectées?

users: 
    uid 
users_removed: 
    uid 
messages: 
    mid 
    uid FK users (uid) 
messages_removed: 
    mid 
    uid 
comments: 
    cid 
    mid FK messages (mid) 
comments_removed: 
    cid 
    mid 
files: 
    fid 
    mid FK messages (mid) 
files_removed: 
    fid 
    mid 

Lorsque je retire enregistrement de la table « utilisateurs » Je veux le déplacer à la table users_removed (avant de supprimer des utilisateurs). Ce que je veux aussi, c'est déplacer tous les messages (et fichiers et commentaires) correspondants vers les tables * _emoved.

J'ai utilisé les déclencheurs:

CREATE TRIGGER delete_user BEFORE DELETE ON users 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO users_removed 
      SELECT * FROM users WHERE uid = OLD.uid; 
     DELETE FROM messages WHERE OLD.uid in (owner_id, author_id); 
    END 
| 

CREATE TRIGGER delete_message BEFORE DELETE ON messages 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO messages_removed 
      SELECT * FROM messages WHERE mid = OLD.mid; 
     DELETE FROM comments WHERE mid = OLD.mid; 
     DELETE FROM files WHERE mid = OLD.mid; 
    END 
| 

CREATE TRIGGER delete_comment BEFORE DELETE ON comments 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO comments_removed 
      SELECT * FROM comments WHERE cid = OLD.cid; 
    END 
| 

CREATE TRIGGER delete_file BEFORE DELETE ON files 
    FOR EACH ROW BEGIN 
     INSERT IGNORE INTO files_removed 
      SELECT * FROM files WHERE fid = OLD.fid; 
    END 
| 

Mais ça marche très lent avec> 50k utilisateurs,> 1m messages, des commentaires et des fichiers.

Existe-t-il une méthode rapide pour cela?

+1

Je l'aurais probablement comme une colonne dans les tables à la place. – sshow

Répondre

1
  1. Il n'y a pas de moyen rapide de le faire. En supposant que vous utilisez InnoDB, vous devez écrire une entrée de table, supprimer une référence d'entrée de table, puis InnoDB effectue une deuxième opération de nettoyage afin de s'en débarrasser (la suppression est coûteuse). Ensuite, avoir ces trous dans votre base de données va certainement finir par nuire aux performances car vous supprimez plus d'utilisateurs au fil du temps.

  2. Si vous enregistrez les informations utilisateur, pourquoi ne pas simplement ajouter une colonne à la table des utilisateurs appelée "active" avec enum (true, false)?

+1

Eh bien ... Je ne peux pas utiliser le champ 'actif', car j'utilise intensivement cette table et l'ajout d'un autre filtre (active = true) rend la lecture très lente. OK. Alors supposons que je ne veux pas que ce soit rapide. C'est assez pour moi de ne pas avoir de verrou de table. Y a-t-il une méthode pour cela? – dryobates

+0

Commencer;/* le travail se passe ici * /; Commettre. Vous utilisez InnoDB, n'est-ce pas? –

Questions connexes