hbm2ddl.auto=update
Bir üretim ortamında veritabanı şemasını güncellemek için yapılandırılmış Hazırda Bekletme uygulamalarını çalıştırmak uygun mudur ?
hbm2ddl.auto=update
Bir üretim ortamında veritabanı şemasını güncellemek için yapılandırılmış Hazırda Bekletme uygulamalarını çalıştırmak uygun mudur ?
Yanıtlar:
Hayır, güvensiz.
Hibernate ekibinin tüm çabalarına rağmen, üretimdeki otomatik güncellemelere güvenemezsiniz . Kendi yamalarınızı yazın, DBA ile inceleyin, test edin, sonra manuel olarak uygulayın.
Teorik olarak, eğer hbm2ddl güncellemesi geliştirmede çalıştıysa, üretimde de çalışmalıdır. Ama gerçekte, her zaman böyle değildir.
İyi çalışsa bile, optimalin altında olabilir. DBA'lara bir sebepten ötürü bu kadar çok para ödenir.
Görev açısından kritik olmayan bir uygulama ve personel üzerinde yüksek ücretli DBA'lar olmadan da üretimde yapıyoruz. İnsan hatasına maruz kalan sadece bir tane daha manuel işlemdir - uygulama farkı algılayabilir ve doğru olanı yapabilir, ayrıca muhtemelen çeşitli geliştirme ve test ortamlarında test ettiniz.
Bir uyarı - kümelenmiş bir ortamda, bundan kaçınmak isteyebilirsiniz, çünkü aynı anda birden fazla uygulama gelebilir ve kötü olabilecek şemayı değiştirmeye çalışabilir. Veya yalnızca bir örneğin şemayı güncellemesine izin verilen bir mekanizma yerleştirin.
Hazırda bekletme oluşturucuları, "Hazırda Bekletme ile Java Kalıcılığı" kitabındaki bir üretim ortamında bunu yapmaktan caydırırlar :
UYARI: Hazırda Bekleme kullanıcılarının bir üretim veritabanının şemasını otomatik olarak güncellemek için SchemaUpdate kullanmaya çalıştıklarını gördük. Bu hızla felaketle sonuçlanabilir ve DBA'nız tarafından izin verilmez.
Güncellemelerin bir değişiklik günlüğünü tutmak için LiquiBase XML dosyasına bakın. Bu yıla kadar hiç kullanmamıştım, ancak DB revizyon kontrolü / geçiş / değişim yönetimini çok kusursuz yapmanın ve öğrenmenin çok kolay olduğunu gördüm. Groovy / Grails projesinde çalışıyorum ve Grails, tüm ORM ("GORM" olarak adlandırılır) altında Hibernate kullanıyor. Uygulamamız yeni özelliklerle geliştikçe oldukça sık yaptığımız tüm SQL şema değişikliklerini yönetmek için Liquibase kullanıyoruz.
Temel olarak, uygulamanız geliştikçe eklemeye devam ettiğiniz değişiklik kümelerinin XML dosyasını saklarsınız. Bu dosya projenizin geri kalanıyla git (ya da kullandığınız her şey) içinde tutulur. Uygulamanız dağıtıldığında, Liquibase bağlandığınız DB'deki changelog tablosunu kontrol eder, böylece daha önce nelerin uygulandığını bilir, daha sonra dosyadan henüz uygulanmamış olan tüm değişiklik kümelerini akıllıca uygular. Uygulamada kesinlikle harika çalışıyor ve tüm şema değişiklikleriniz için kullanıyorsanız, ödeme ve dağıttığınız kodun her zaman tam uyumlu bir veritabanı şemasına bağlanabileceğinden% 100 emin olabilirsiniz.
Harika şey, dizüstü bilgisayarımda tamamen boş bir kayrak mysql veritabanı alabilir, uygulamayı tetikleyebilir ve hemen şema benim için ayarlanmış olmasıdır. Ayrıca, bunları bir local-dev'e veya aşamalı db'ye uygulayarak şema değişikliklerini test etmeyi kolaylaştırır.
Başlamak için en kolay yol muhtemelen mevcut DB'nizi almak ve daha sonra bir başlangıç baseline.xml dosyası oluşturmak için Liquibase kullanmak olacaktır. Sonra gelecekte ona ekleyebilir ve likibazın şema değişikliklerini yönetmesine izin verebilirsiniz.
hbm2ddl.auto=update
böylece Sınıf / DB eşleşmeleri doğrulanır ve likibaz aracılığıyla DB oluşturma tam denetime sahip eklemek olacaktır. Ne düşünüyorsun?
validate
Hayır oyu veririm. Hazırda bekletme, sütunların veri türlerinin ne zaman değiştiğini anlamıyor gibi görünüyor. Örnekler (MySQL kullanarak):
String with @Column(length=50) ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)
@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed
Bir String sütununun uzunluğunu 255'in üzerine çıkarmak ve metne, orta metne vb. Dönüştürdüğünü görmek gibi başka örnekler de olabilir.
Verilmiş, yeni bir sütun oluşturmadan, verileri kopyalayıp eski sütunu havaya uçurmadan "veri tiplerini dönüştürmenin" bir yolu olduğunu düşünmüyorum. Ancak veritabanınızın, hazırda bulunduğunuz Hazırda Bekletme eşlemesini yansıtmayan sütunları çok tehlikeli bir şekilde yaşıyor olmanız ...
Flyway bu sorunla başa çıkmak için iyi bir seçenektir:
@Column(length = 45)
için @Column(length = 255)
. Hazırda Beklet 4.3.6.Final'ın kullanarak veritabanı şemasını doğru şekilde güncellediğini doğrulayabilir hbm2ddl.auto=update
. (Bahsetmemiz gereken bir şey, veritabanında şu anda herhangi bir veri bulunmamasıdır - sadece yapı.)
Hibernate, ne yaptıklarını bilmeyen insanlar kullanılmaması gereken durumlarda kullandıklarında, kendilerini otomatik olarak güncellemek için prod'da otomatik güncellemeleri kullanmama konusunda feragat etmek zorundadır.
Kullanılmaması gereken durumların, iyi olduğu durumlardan çok daha fazla olduğu belirtildi.
Yıllardır birçok farklı projede kullandım ve hiçbir zaman tek bir sorunum olmadı. Bu topal bir cevap değil ve kovboy kodlaması değil. Bu tarihi bir gerçek.
"Asla üretimde yapma" diyen bir kişi, aşina olduğu belirli bir üretim dağıtımları dizisi düşünüyor (şirketi, endüstrisi, vb.).
"Üretim dağıtımları" evreni geniş ve çeşitlidir.
Deneyimli bir Hazırda Bekletme geliştiricisi, belirli bir eşleme yapılandırmasından DDL'nin ne olacağını tam olarak bilir. Test ettiğiniz ve DDL'de beklediğiniz şeyin (dev, qa, sahneleme vb.) Sonuçlandığını doğruladığınız sürece, iyisiniz.
Çok sayıda özellik eklerken, otomatik şema güncellemeleri gerçek zamanlı bir tasarruf olabilir.
Otomatik güncellemelerin işlemeyeceği şeyler sonsuzdur, ancak bazı örnekler veri taşıma, boş bırakılamayan sütunlar ekleme, sütun adı değişiklikleri vb.
Ayrıca kümelenmiş ortamlarda dikkatli olmanız gerekir.
Ama sonra tekrar, tüm bunları biliyor olsaydınız, bu soruyu sormazdınız. Hmm. . . Tamam, bu soruyu soruyorsanız, hazırda kullanmayı düşünmeden önce Hazırda Beklet ve otomatik şema güncellemeleri konusunda çok fazla deneyiminiz olmasını beklemelisiniz.
Bu makalede açıkladığım gibi hbm2ddl.auto
, üretimde kullanmak iyi bir fikir değil .
Veritabanı şemasını yönetmenin tek yolu artımlı geçiş komut dosyalarını kullanmaktır, çünkü:
Hazırda Bekletme Kullanıcı Kılavuzu bile hbm2ddl
aracı üretim ortamları için kullanmaktan kaçınmanızı önerir .
SchemaExport
Bu test senaryosunda gösterildiği gibi kullanın .
Bunu aylardır üretimde olan bir projede yapıyoruz ve şimdiye kadar hiç problem yaşamadık. Bu tarif için gereken 2 malzemeyi unutmayın:
Bir geriye dönük uyumluluk yaklaşımı ile tasarlayın nesne modeli kullanımdan kaldırmak nesneler ve onları değiştirerek / kaldırmak yerine bağlıyor. Bu, bir nesnenin veya özniteliğin adını değiştirmeniz gerekirse, eskisini olduğu gibi bırakın, yenisini ekleyin ve bir çeşit taşıma komut dosyası yazın. Nesneler arasındaki bir ilişkiyi değiştirmeniz gerekiyorsa, zaten üretimdeyseniz, bu tasarımınızın ilk başta yanlış olduğu anlamına gelir, bu nedenle eski verileri etkilemeden yeni ilişkiyi ifade etmenin yeni bir yolunu düşünmeye çalışın.
Dağıtımdan önce her zaman veritabanını yedekleyin .
Benim düşüncem - bu yazıyı okuduktan sonra - bu tartışmaya katılan insanların% 90'ının sadece üretim ortamında böyle otomasyonların kullanılması düşüncesiyle dehşete düştüğü. Bazıları topu DBA'ya atıyor. Tüm üretim ortamlarının bir DBA sağlayamayacağını ve pek çok geliştirici ekibin bir tane karşılayamayacağını (en azından orta ölçekli projeler için) düşünün. Yani, herkesin her şeyi yapması gereken takımlardan bahsediyorsak, top onların üzerindedir.
Bu durumda, neden sadece her iki dünyanın da en iyisini yapmaya çalışmıyorsunuz? Bunun gibi araçlar, dikkatli bir tasarım ve planla birçok durumda yardımcı olabilecek bir yardım eli vermek için burada. Ve inan bana, yöneticiler başlangıçta ikna etmek zor olabilir, ancak topun ellerinde olmadığını biliyorlarsa, sevecekler.
Şahsen, herhangi bir şemayı genişletmek için komut dosyaları yazmaya asla geri dönemezdim, ama bu sadece benim düşüncem. Ve son zamanlarda NoSQL şema içermeyen veritabanlarını benimsemeye başladıktan sonra, yakında tüm bu şema tabanlı işlemlerin geçmişe ait olduğunu görebiliyorum, bu yüzden perspektifinizi değiştirmeye ve ileriye bakmaya daha iyi başlayabilirsiniz.
Bunu riske atmam, çünkü korunmuş olması gereken verileri kaybedebilirsiniz. hbm2ddl.auto = update, dev veritabanınızı güncel tutmanın kolay bir yoludur.
Benim durumumda (Hibernate 3.5.2, Postgresql, Ubuntu), ayar hibernate.hbm2ddl.auto=update
yalnızca yeni tablolar oluşturdu ve zaten var olan tablolarda yeni sütunlar oluşturdu.
Ne tabloları düşürdü, ne sütunları bıraktı, ne sütunları değiştirdi. Güvenli bir seçenek olarak adlandırılabilir, ancak hibernate.hbm2ddl.auto=create_tables add_columns
bunun gibi bir şey daha açık olacaktır.
Güvenli değil, önerilmiyor, ancak mümkün.
Üretimdeki otomatik güncelleme seçeneğini kullanan bir uygulamada deneyimim var.
Bu çözümde bulunan ana sorunlar ve riskler şunlardır:
Bu nedenle, otomatik güncellemeyi üretimde kullanmanızı önermeyeceğim.
Otomatik güncellemeyi gerçekten üretimde kullanmak istiyorsanız, tavsiye ederim:
Ve, diğer yayınlardan farklı olarak, otomatik güncellemenin "çok iyi ücretli" DBA'larla (diğer yayınlarda belirtildiği gibi) etkinleştirildiğini düşünmüyorum. DBA'ların tabloları ve sütunları oluşturmak / değiştirmek / silmek için SQL ifadeleri yazmaktan daha önemli şeyleri vardır. Bu basit günlük görevler geliştiriciler tarafından yapılabilir ve otomatikleştirilebilir ve Hibernate ve DBA'ların bunları yazmak için "çok iyi ödenmiş" olması gerekmeden yalnızca DBA ekibinin gözden geçirilmesi için geçilebilir.
Genellikle büyük kuruluşlardaki kurumsal uygulamalar düşük ayrıcalıklarla çalışır.
Veritabanı kullanıcı adının, gerektiren DDL
sütun ekleme yetkisi olmayabilir hbm2ddl.auto=update
.
Vladimir'e katılıyorum. Böyle bir kursu bile önerirsem şirketimdeki yöneticiler kesinlikle takdir etmeyeceklerdi.
Ayrıca, Hibernate'e körü körüne güvenmek yerine bir SQL komut dosyası oluşturmak, artık kullanılmayan alanları kaldırma fırsatı verir. Hazırda Beklet bunu yapmaz.
Ve üretim şemasını yeni şema ile karşılaştırmanın veri modelinde değiştirdiğiniz wat hakkında daha iyi bir fikir verdiğini görüyorum. Biliyorsunuz, elbette, çünkü bunu yaptınız, ama şimdi tek seferde tüm değişiklikleri görüyorsunuz. Seni "Ne halt ?!"
Sizin için bir şema deltası oluşturabilecek araçlar var, bu yüzden zor bir iş bile değil. Ve sonra tam olarak ne olacağını biliyorsun.
Uygulamaların şeması zaman içinde gelişebilir; farklı sürümlerde olabilecek birkaç yüklemeniz varsa, uygulamanızın, bir tür aracın veya komut dosyasının bir şema ve verileri kademeli olarak bir sürümden diğerine geçirebilmesini sağlamak için bir yolunuz olmalıdır.
Hazırda Bekletme eşleştirmelerinde (veya ek açıklamalarında) tüm kalıcılığınızın olması, şema evrimini kontrol altında tutmanın çok iyi bir yoludur.
Şema evriminin dikkate alınması gereken birkaç yönü olduğunu düşünmelisiniz:
daha fazla sütun ve tablo eklemede veritabanı şemasının gelişimi
eski sütunları, tabloları ve ilişkileri bırakmak
yeni sütunları varsayılan değerlerle doldurma
Hazırda bekletme araçları özellikle benim deneyimim gibi birçok farklı türde veritabanında aynı uygulamanın farklı sürümlerine sahip olmanız durumunda önemlidir.
Yeni bir boolean değerli özellik veya sayısal özellik girmeniz durumunda olduğu gibi, Hazırda Bekletme'yi kullanmanız durumunda 3. Nokta çok hassastır, eğer Hazırda Bekleme bir istisna oluşturacaksa bu tür sütunlarda boş değer bulursa.
Öyleyse ne yapacağım: gerçekten şema güncellemesinin Hazırda Bekletme araçları kapasitesini kullanın, ancak varsayılan değerlerin doldurulması, artık kullanılmayan sütunların bırakılması ve benzeri gibi bazı veri ve şema bakım geri aramaları eklemeniz gerekir. Bu şekilde avantajlar elde edersiniz (veritabanından bağımsız şema güncelleme komut dosyaları ve güncellemelerin yinelenen kodlamasından kaçınılması), ancak işlemin tüm yönlerini de kapsarsınız.
Örneğin, bir sürüm güncellemesi, varsayılan olarak null değerine ayarlanabilen varchar değerli bir özellik (bu nedenle sütun) eklemekten ibaretse, otomatik güncelleme ile yapılacaktır. Daha fazla karmaşıklık gerektiğinde, daha fazla çalışma gerekecektir.
Bu, güncelleme yapıldığında uygulamanın şemasını güncelleyebileceğini varsayabilir (yapılabilir), bu da şemada bunu yapmak için kullanıcı haklarına sahip olması gerektiği anlamına gelir. Müşterinin politikası bunu önlüyorsa (muhtemelen Lizard Brain vakası), veritabanına özgü komut dosyalarını sağlamanız gerekir.