2009-06-01 4 views
8

J'essaie de copier une table sur une autre "atomiquement". Fondamentalement je veux mettre à jour une table périodiquement, de sorte qu'un processus qui lit de la table n'obtiendra pas un résultat incomplet si un autre processus met à jour la table.Copie atomique d'une table MySQL plutôt qu'une autre?

Pour donner quelques informations d'arrière-plan, je veux une table qui sert de classement pour un jeu. Ce classement sera mis à jour toutes les quelques minutes via un processus séparé. Mon raisonnement est le suivant:

Le tableau SCORES contient le classement visible par le public qui sera lu à partir du moment où un utilisateur consulte le leaderboard. Cette table est mise à jour toutes les quelques minutes. Le processus qui met à jour le leaderboard va créer une table SCORES_TEMP contenant le nouveau leaderboard. Une fois cette table créée, je veux copier tout son contenu sur SCORES "atomiquement". Je pense que ce que je veux faire est quelque chose comme:

TRUNCATE TABLE SCORES; 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP; 

Je veux tout remplacer dans SCORES. Je n'ai pas besoin de conserver mes clés primaires ou mes valeurs d'incrémentation automatique. Je veux juste apporter toutes les données de SCORES_TEMP. Mais je sais que si quelqu'un voit les scores avant que ces 2 déclarations soient faites, le classement sera vide. Comment puis-je faire cela atomiquement, de sorte qu'il ne montrera jamais des données vierges ou incomplètes? Merci!

Répondre

11

Utilisez rename table

RENAME TABLE old_table TO backup_table, new_table TO old_table; 

Il est atomique, fonctionne sur tout le stockage moteurs, et n'a pas à reconstruire ILD les index.

+0

Les transactions aideront certainement maintenant que je sais qu'elles peuvent accomplir les besoins atomiques que j'ai, mais pour la simplicité, cette solution de changement de nom de table est la meilleure pour ceci situation particulière. Merci tout le monde! – DivideByHero

2

En MySQL, en raison de the behavior of TRUNCATE Je pense que vous aurez besoin de:

BEGIN TRANSACTION; 
DELETE FROM SCORES; 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP; 
COMMIT TRANSACTION; 

Je ne suis pas sûr qu'il ya un moyen de faire ce qui est toujours effectivement une transaction d'opération de sécurité DDL.

+0

Qu'est-ce qu'une opération DDL? Merci ... – DivideByHero

+0

DDL = langage de définition de données - des choses comme CREATE TABLE, etc. –

0

Je ne sais pas traite de MySQL chaud avec transaction, mais dans T-SQL vous pouvez écrire

BEGIN TRAN 
DELETE FROM SCORES 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP 
COMMIT TRAN 

De cette façon, votre opération serait « atomique », mais pas instantanée.

2

Vous pouvez utiliser des transactions (pour InnoDB),

BEGIN TRANSACTION; 
DELETE FROM SCORES; 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP; 
COMMIT; 

ou LOCK TABLES (pour MyISAM):

LOCK TABLES; 
DELETE FROM SCORES; 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP; 
UNLOCK TABLES; 
Questions connexes