Chà ... Hừ. Trong nhiều năm không ai đề cập đến một điều tinh tế.
Mặc dù DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );
có vẻ hợp lý, nó dẫn đến một tình huống khi bảng cũ đã biến mất và bảng mới chưa được tạo: một số khách hàng có thể cố gắng truy cập bảng chủ đề ngay tại thời điểm này.
Cách tốt hơn là tạo một bảng hoàn toàn mới và trao đổi nó với một bảng cũ (nội dung bảng bị mất):
CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
- Bạn nên kiểm tra kết quả
CREATE ...
và không tiếp tục trong trường hợp có lỗi , vì thất bại có nghĩa là luồng khác không hoàn thành cùng một tập lệnh: vì nó bị lỗi ở giữa hoặc chưa hoàn thành - đó là một ý tưởng hay tự kiểm tra mọi thứ
- Sau đó, bạn nên kiểm tra kết quả đầu tiên
RENAME ...
và không tiếp tục trong trường hợp thành công : toàn bộ hoạt động được hoàn thành thành công; thậm chí nhiều hơn, chạy tiếp theo RENAME ...
có thể (và sẽ) không an toàn nếu một luồng khác đã bắt đầu trình tự tương tự (tốt hơn là bao gồm trường hợp này hơn là không che, xem ghi chú khóa bên dưới).
- Nguyên
RENAME ...
tử thứ hai thay thế định nghĩa bảng, tham khảo
hướng dẫn sử dụng MySQL
để biết chi tiết.
- Cuối cùng,
DROP ...
chỉ cần dọn dẹp bàn cũ, rõ ràng.
Kết hợp tất cả các câu lệnh với một cái gì đó như SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');
cho phép gọi tất cả các câu lệnh một cách tuần tự mà không kiểm tra lỗi, nhưng tôi không nghĩ đó là một ý tưởng hay: tăng độ phức tạp và các chức năng khóa trong MySQL không an toàn cho sao chép dựa trên câu lệnh.
Nếu dữ liệu bảng sẽ tồn tại nâng cấp định nghĩa bảng ... Trong trường hợp chung, câu chuyện phức tạp hơn nhiều về việc so sánh các định nghĩa bảng để tìm ra sự khác biệt và đưa ra ALTER ...
tuyên bố phù hợp , điều này không phải lúc nào cũng có thể tự động, ví dụ như khi các cột được đổi tên.
Lưu ý bên 1:
Bạn có thể xử lý các chế độ xem bằng cách sử dụng cùng một cách tiếp cận, trong trường hợp này CREATE/DROP TABLE
chỉ chuyển đổi thành CREATE/DROP VIEW
trong khi RENAME TABLE
vẫn không thay đổi. Trong thực tế, bạn thậm chí có thể biến bảng thành xem và ngược lại.
CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;
Lưu ý phụ 2:
Người dùng MariaDB nên hài lòng CREATE OR REPLACE TABLE/VIEW
, điều này đã quan tâm đến vấn đề chủ đề và đó là điểm tốt.