2009-06-01 30 views
8

Estoy tratando de copiar una tabla sobre otra "atómicamente". Básicamente quiero actualizar una tabla periódicamente, de modo que un proceso que lea de la tabla no obtenga un resultado incompleto si otro proceso está actualizando la tabla.¿Copiando automáticamente una tabla MySQL sobre otra?

Para dar algunos antecedentes, quiero una tabla que sirva como tabla de clasificación para un juego. Esta tabla de clasificación se actualizará cada pocos minutos a través de un proceso por separado. Mi pensamiento es el siguiente:

La tabla PUNTUACIONES contiene la tabla de clasificación pública que se leerá cuando un usuario vea la tabla de clasificación. Esta tabla se actualiza cada pocos minutos. El proceso que actualiza la tabla de clasificación creará una tabla SCORES_TEMP que contiene la nueva tabla de clasificación. Una vez que se crea esa tabla, quiero copiar todo su contenido en PUNTUACIONES "atómicamente". Creo que lo que quiero hacer es algo así como:

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

Quiero reemplazar todo en PUNTUACIONES. No necesito mantener mis claves primarias o valores de incremento automático. Solo quiero traer todos los datos de SCORES_TEMP. Pero sé que si alguien ve los puntajes antes de que se realicen estas dos declaraciones, la tabla de clasificación estará en blanco. ¿Cómo puedo hacer esto atómicamente, de modo que nunca muestre datos en blanco o incompletos? ¡Gracias!

Respuesta

11

Uso rename table

RENAME TABLE old_table TO backup_table, new_table TO old_table; 

Es atómica, funciona en todo el almacenamiento motores, y no tiene que rebu ild los índices.

+0

Las transacciones definitivamente serán útiles ahora que sé que pueden lograr las necesidades atómicas que tengo, pero para simplificar, esta solución de cambio de nombre de tabla es la mejor para esto situación particular. ¡Gracias a todos! – DivideByHero

2

En MySQL, debido a the behavior of TRUNCATE creo que necesita para:

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

No estoy seguro de que hay una manera de hacer lo que siempre es efectivamente una transacción segura operación DDL.

+0

¿Qué es una "operación DDL"? Gracias ... – DivideByHero

+0

DDL = lenguaje de definición de datos - cosas como CREATE TABLE, etc. –

0

No sé trata MySQL calientes con la transacción, pero en T-SQL que podría escribir

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

De esta manera su operación sería "atómica", pero no es instantánea.

2

Es posible utilizar las transacciones (por InnoDB),

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

o LOCK TABLES (por MyISAM):

LOCK TABLES; 
DELETE FROM SCORES; 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP; 
UNLOCK TABLES; 
Cuestiones relacionadas