2009-06-01 2 views
8

Я пытаюсь скопировать один стол над другим «атомарно». В основном я хочу периодически обновлять таблицу, так что процесс, который читает из таблицы, не получит неполного результата, если другой процесс обновляет таблицу.Атомное копирование одной таблицы MySQL поверх другой?

Чтобы предоставить некоторую справочную информацию, мне нужна таблица, которая выступает в качестве таблицы лидеров для игры. Эта таблица лидеров будет обновляться каждые несколько минут через отдельный процесс. Мое мышление выглядит следующим образом:

Таблица SCORES содержит общедоступную таблицу лидеров, которая будет считана с момента, когда пользователь просмотрит таблицу лидеров. Эта таблица обновляется каждые несколько минут. Процесс, который обновляет таблицу лидеров, создаст таблицу SCORES_TEMP, содержащую новую таблицу лидеров. Когда эта таблица будет создана, я хочу скопировать все ее содержимое в SCORES «атомарно». Я думаю, что я хочу сделать следующее:

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

Я хочу заменить все в SCORES. Мне не нужно поддерживать мои первичные ключи или значения автоматического увеличения. Я просто хочу записать все данные из SCORES_TEMP. Но я знаю, что если кто-то просмотрит оценки до того, как эти 2 заявления будут сделаны, таблица лидеров будет пустой. Как я могу сделать это атомарно, чтобы он никогда не показывал пустые или неполные данные? Благодаря!

ответ

11

Использование rename table

RENAME TABLE old_table TO backup_table, new_table TO old_table; 

Это атомная, работает на всех хранения двигателей и не нуждается в переустройстве ild индексов.

+0

Сделки определенно помогут теперь, когда я знаю, что они могут выполнить атомные потребности, которые у меня есть, но для простоты это решение переименования таблицы является лучшим для этого конкретная ситуация. Всем спасибо! – DivideByHero

2

В MySQL, из-за the behavior of TRUNCATE я думаю, что вам нужно:

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

Я не уверен, что есть способ сделать то, что всегда эффективно операция транзакции DDL безопасности.

+0

Что такое "DDL-операция"? Спасибо ... – DivideByHero

+0

DDL = язык определения данных - такие вещи, как CREATE TABLE и т. Д. –

0

Я не знаю, горячие MySQL сделки с сделкой, но в T-SQL вы можете написать

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

Таким образом, ваша работа будет «атомной», но не мгновенно.

2

Вы можете использовать транзакции (для InnoDB),

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

или LOCK TABLES (для MyISAM):

LOCK TABLES; 
DELETE FROM SCORES; 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP; 
UNLOCK TABLES; 
Смежные вопросы