Şey ... Ha. Yıllarca kimse ince bir şeyden bahsetmedi.
Rağmen DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );
makul görünüyor eski tablo zaten gitti ve yenisi henüz oluşturulmadı zaman, bir duruma yol açar: Bazı istemci su anda erişim konusu masaya deneyebilir.
Daha iyi bir yol, yepyeni bir tablo oluşturmak ve eskisiyle değiştirmek (tablo içeriği kaybolur):
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`;
- Hata sonucunu kontrol etmelisiniz ve hata durumunda
CREATE ...
devam etmemelisiniz , çünkü başarısızlık diğer iş parçacıkları aynı komut dosyasını bitirmediği anlamına gelir: ya ortada çöktüğü ya da henüz bitirmediği için - bu iyi bir fikirdir şeyleri kendiniz kontrol edin.
- Ardından, önce sonucunu kontrol etmeli
RENAME ...
ve başarı durumunda devam etmemelisiniz : tüm işlem başarıyla tamamlandı; daha da fazlası, RENAME ...
başka bir iş parçacığı aynı sırayla başlatılmışsa , sonraki çalıştırma güvenli olmayabilir (ve olacaktır) (bu durumu kapsamamaktan ziyade kapsamak daha iyidir, aşağıdaki kilitleme notuna bakın).
- İkincisi
RENAME ...
atomik olarak tablo tanımının yerini alır,
ayrıntılar için
MySQL kılavuzuna bakın.
- Sonunda,
DROP ...
sadece eski masayı temizler.
Gibi bir şey ile tüm ifadeleri kaydırma SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');
sadece hata denetimi olmadan tüm ifadeleri sırayla çağırmak için izin verir, ancak bunun iyi bir fikir olduğunu sanmıyorum: MySQL karmaşıklık artar ve kilitleme işlevleri deyim tabanlı çoğaltma için güvenli değildir.
Tablo verilerinin tablo tanımı güncellemesinden sağ çıkması gerekiyorsa ... Genel durumda, farklılıkları bulmak ve doğru ALTER ...
ifadeleri üretmek için tablo tanımlarını karşılaştırmak çok daha karmaşık bir hikaye .
Yan Not 1:
Bu durumda aynı yaklaşımı kullanarak görünümleri, başa çıkabilirim CREATE/DROP TABLE
sadece dönüşmektedir CREATE/DROP VIEW
ise RENAME TABLE
değişmeden kalır. Aslında tabloyu görünüme veya tam tersine bile dönüştürebilirsiniz.
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`;
Yan not 2:
MariaDB kullanıcıları CREATE OR REPLACE TABLE/VIEW
, konu sorununu zaten önemseyen mutlu olmalı ve iyi noktalar.