2009-06-01 43 views
8

Tôi đang cố gắng sao chép một bảng qua một bảng khác "nguyên tử". Về cơ bản tôi muốn cập nhật một bảng định kỳ, như vậy mà một quá trình đọc từ bảng sẽ không nhận được một kết quả không đầy đủ nếu một quá trình đang cập nhật bảng.Sao chép nguyên tử một bảng MySQL sang bảng khác?

Để cung cấp một số thông tin cơ bản, tôi muốn một bảng hoạt động như một bảng thành tích cho trò chơi. Bảng xếp hạng này sẽ cập nhật vài phút một lần thông qua một quy trình riêng biệt. Suy nghĩ của tôi như sau:

Bảng SCORES chứa bảng thành tích có thể xem công khai sẽ được đọc từ khi người dùng xem bảng xếp hạng. Bảng này được cập nhật vài phút một lần. Quá trình cập nhật bảng xếp hạng sẽ tạo ra một bảng SCORES_TEMP chứa bảng thành tích mới. Khi bảng đó được tạo, tôi muốn sao chép tất cả nội dung của nó sang SCORES "nguyên tử". Tôi nghĩ điều tôi muốn làm là:

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

Tôi muốn thay thế mọi thứ trong SCORES. Tôi không cần phải duy trì các khóa chính hoặc giá trị tăng tự động của mình. Tôi chỉ muốn mang tất cả dữ liệu từ SCORES_TEMP. Nhưng tôi biết rằng nếu ai đó xem điểm số trước khi 2 câu này được thực hiện, bảng thành tích sẽ trống. Làm thế nào tôi có thể làm điều này một cách nguyên tử, sao cho nó sẽ không bao giờ hiển thị dữ liệu trống hoặc không đầy đủ? Cảm ơn!

Trả lời

11

Sử dụng rename table

RENAME TABLE old_table TO backup_table, new_table TO old_table; 

Đó là nguyên tử, hoạt động trên tất cả các lưu trữ động cơ và không phải rebu ild các chỉ mục.

+0

Giao dịch chắc chắn sẽ giúp tôi biết rằng họ có thể thực hiện các nhu cầu nguyên tử mà tôi có, nhưng để đơn giản, giải pháp đổi tên bảng này là tốt nhất cho điều này tình hình cụ thể. Cảm ơn mọi người! – DivideByHero

2

Trong MySQL, vì the behavior of TRUNCATE Tôi nghĩ rằng bạn sẽ cần phải:

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

Tôi không chắc chắn có một cách để làm những gì luôn luôn là một cách hiệu quả giao dịch hoạt động DDL an toàn.

+0

"Hoạt động DDL" là gì? Cảm ơn ... – DivideByHero

+0

DDL = ngôn ngữ định nghĩa dữ liệu - những thứ như CREATE TABLE, vv –

0

Tôi không biết giao dịch MySQL nóng với giao dịch, nhưng trong T-SQL bạn có thể viết

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

Bằng cách này hoạt động của bạn sẽ là "nguyên tử", nhưng không phải ngay lập tức.

2

Bạn có thể sử dụng các giao dịch (đối với InnoDB),

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

hoặc LOCK TABLES (ví MyISAM):

LOCK TABLES; 
DELETE FROM SCORES; 
INSERT INTO SCORES SELECT * FROM SCORES_TEMP; 
UNLOCK TABLES; 
Các vấn đề liên quan