Baiklah ... Hah. Selama bertahun-tahun tidak ada yang menyebutkan satu hal yang halus.
Meskipun DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );
tampaknya masuk akal, ini mengarah ke situasi ketika tabel lama sudah hilang dan yang baru belum dibuat: beberapa klien mungkin mencoba mengakses tabel subjek tepat pada saat ini.
Cara yang lebih baik adalah membuat tabel baru dan menukarnya dengan yang lama (isi tabel hilang):
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`;
- Anda harus memeriksa hasil
CREATE ...
dan jangan melanjutkan jika ada kesalahan , karena kegagalan berarti bahwa utas lain tidak menyelesaikan skrip yang sama: baik karena terhenti di tengah atau baru saja tidak selesai - itu ide yang baik untuk periksa semuanya sendiri.
- Kemudian, Anda harus memeriksa hasilnya terlebih dahulu
RENAME ...
dan jangan melanjutkan jika berhasil : seluruh operasi berhasil diselesaikan; bahkan lebih, menjalankan selanjutnya RENAME ...
dapat (dan akan) tidak aman jika utas lain sudah memulai urutan yang sama (lebih baik untuk menutup kasus ini daripada tidak untuk menutupi, lihat mengunci catatan di bawah).
- Kedua
RENAME ...
secara atom menggantikan definisi tabel, lihat
manual MySQL
untuk detailnya.
- Akhirnya,
DROP ...
membersihkan meja lama, jelas.
Membungkus semua pernyataan dengan sesuatu seperti SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');
memungkinkan untuk menjalankan semua pernyataan secara berurutan tanpa pengecekan kesalahan, tapi saya rasa itu bukan ide yang bagus: kompleksitas meningkat dan fungsi penguncian di MySQL tidak aman untuk replikasi berbasis pernyataan.
Jika data tabel harus selamat dari peningkatan definisi tabel ... Untuk kasus umum, ini adalah cerita yang jauh lebih kompleks tentang membandingkan definisi tabel untuk menemukan perbedaan dan menghasilkan ALTER ...
pernyataan yang tepat , yang tidak selalu memungkinkan secara otomatis, misalnya ketika kolom diganti nama.
Side note 1:
Anda dapat menangani dengan pemandangan menggunakan pendekatan yang sama, dalam hal ini CREATE/DROP TABLE
hanya mengubah ke CREATE/DROP VIEW
sedangkan RENAME TABLE
sisa-sisa tidak berubah. Bahkan Anda bahkan dapat mengubah tabel menjadi tampilan dan sebaliknya.
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`;
Catatan 2:
Pengguna MariaDB harus senang CREATE OR REPLACE TABLE/VIEW
, yang sudah peduli dengan masalah subjek dan itu poin yang baik.