2010-05-20 10 views
1

J'ai un Tableau de données et un Tableau d'archives.Atomique [déplacer vers un autre tableau, puis supprimer les données d'origine]

Une webapp verse des données dans le tableau des données , et une tâche cron tire les données toutes les heures et les archives dans l'archive tableau (ce qui maintient la petite table de données et rapide à travailler avec).

Comme je le vois, il y a deux requêtes psudo-SQL à exécuter:

INSERT Archive SELECT * FROM Data; 

&

DELETE FROM Data; 

Cependant, je ne veux que de supprimer les données qui a été copié avec succès, si la copie échoue je veux qu'il soit laissé dans un état cohérent, avec les données ni à moitié déplacé, ni supprimé.

Quelle est la bonne façon de procéder?

Répondre

6

Avec une transaction.

start transaction; 
insert into archive select * from data; 
delete from data where primary_key in (select primary_key from archive); 
commit; 
+0

Certains systèmes de bases de données ne sont pas cohérentes sur les requêtes au cours des transactions, uniquement sur les mises à jour, de sorte que « supprimer des données » ou non supprimer des choses qui était ajouté après l'insertion, c'est pourquoi je suggère d'utiliser une requête dans la suppression. –

+0

Je pense que vous vouliez sélectionner dans la sous-requête la table d'archivage: 'delete from data where primary_key in (sélectionnez primary_key from archive);' –

+2

De même, 'begin transaction' n'est pas une commande MySQL valide. La commande appropriée est 'start transaction'. –

1

Je recommande d'utiliser la syntaxe de suppression multi-tables et de vous joindre à la table d'archivage pour votre suppression. De cette façon, vous supprimez uniquement les lignes qui se trouvent dans les deux tables.

Exemple simple:

insert into archive select * from data; 
delete data.* 
from data 
inner join archive on archive.id = data.id; 

Au-delà, vous voudrez peut-être envisager de briser ce en petits morceaux pour une meilleure performance. Par exemple:

insert into archive select * from data where id > 1000 and id <= 2000; 
delete data.* 
from data 
inner join archive on archive.id = data.id 
where data.id > 1000 and data.id <= 2000; 

A partir du manuel: http://dev.mysql.com/doc/refman/5.1/en/delete.html