İlişkisel veritabanları ve yinelemeli gelişim


19

Çevik metodolojiler, Etki Alanına Dayalı Tasarım ve Nesneye Dayalı Analiz ve Tasarım gibi yazılım geliştirmeye yönelik birçok yaklaşımda, geliştirmeye tek bir yinelemeli yaklaşım benimsememiz teşvik edilir.

Bu yüzden, projede ilk çalışmaya başladığımızda alan modelimizi doğru bir şekilde yapmamız gerekmiyor. Bunun yerine, zaman geçtikçe modeli yeniden düzenliyoruz çünkü sorunlu alanı zamanla daha iyi anlıyoruz.

Bunun dışında, zaten çok ikna olduğum mükemmel bir model almaya çalışsak bile, gereksinimler değişebilir. Yazılım Yani sonra gelmiştir üretime dağıtıldıktan, son kullanıcılar belli bir gereklilik tamamen anlaşılmamış olduğunu fark edebilirsiniz, ya da daha kötüsü, bazı gereklilik eksikti.

Buradaki nokta, yazılım dağıtıldıktan sonra modeli değiştirmemiz gerekebileceğidir. Bu durumda bir sorunumuz vardır: üretim veritabanında , önemli olan ve eski modelin biçimine zaten yerleştirilmiş olan kullanıcı verileri bulunur .

Kod iyi tasarlanmamışsa ve sistem büyükse kodu güncellemek zor olabilir. Ancak zamanla yapılabilir, Git gibi üretime hazır sürüme zarar vermeden bunu yapmamıza yardımcı olan araçlarımız var.

Öte yandan, model değişirse, sınıfların özellikleri kaybolursa ya da her neyse, veritabanı da değişmelidir. Ama bir sorunumuz var: orada eski model için zaten oluşturulmuş, kaybolamayacak veriler var.

Buradaki ilişkisel bir veritabanı, son kullanıcılar tarafından istendiğinde yinelemeli geliştirme yapmamızı ve hatta yazılımı güncellememizi engelleyen bir engel gibi görünüyor.

Daha önce kullandığım bir yaklaşım, eski veritabanı tablolarını yenileriyle eşleştiren özel bir sınıfı kodlamaktı. Bu sınıflar verileri eski biçimde seçer, yeni model tarafından kullanılan formata dönüştürür ve yeni tablolara kaydeder.

Bu yaklaşım en iyisi gibi görünmüyor. Buradaki sorum şudur: İlişkisel veritabanlarıyla yinelemeli gelişimi uzlaştırmak için iyi bilinen ve önerilen yaklaşımlar var mı?


6
Bu arada, bunun özellikle ilişkisel veritabanları ile ilgisi olduğunu düşünmüyorum . Üzerinde çalıştığım bir projeyle benzer bir sorunum var, ancak çok ilişkisel olmayan nesneleri temsil eden JSON dizelerimizin şemasını yaşıyoruz. Muhtemelen tüm sebat biçimlerini eşit olarak etkiler.
Ixrec

1
Veritabanı şemasını veri kaybetmeyecek şekilde değiştirirsiniz, en.wikipedia.org/wiki/Schema_migration .
RemcoGerlich

1
Bu konunun daha önce bir yerde yoğun bir şekilde tartışıldığından eminim, sadece Programcılar'da bulamıyorum. Ancak buraya bakın martinfowler.com/articles/evodb.html veya buraya stackoverflow.com/questions/334059/…
Doc Brown

1
Diyerek şöyle devam etti: "Bunun dışında, zaten çok ikna olduğum mükemmel bir model almaya çalışsak bile, gereksinimler değişebilir." Ben (mükemmel yakın) modeli ön almak için bile denemek gerektiğini eklemek istiyorum. Bu, seçeneklerinizi açık tutmak yerine zihniyetinizi tek bir çözüm türüne bağlayabilir.
Bent

Yanıtlar:


15

Özel sınıflar olmak zorunda değildir, ancak evet, veritabanını önceki formatta alıp onu geçerli biçime dönüştürecek bir şeye ihtiyacınız vardır.

Buradaki şey, test ve üretim veritabanlarına asla elle değil, her zaman geçiş komut dosyalarına dokunmak için bu komut dosyalarını ve disiplini yazmak ve test etmek için bir süreç geliştirmeniz gerektiğidir.

Veritabanında her değişiklik yapmanız gerektiğinde, SQL'de veya ORM katmanınızı kullanıyorsa, bunu yapacak bir komut dosyası yazarsınız ve yeni şemayı gerektiren değişikliklerle birlikte sürüm denetiminize kaydedersiniz. Sonra, henüz bir sırayla uygulanmayan tüm geçiş komut dosyalarını uygulayarak veritabanını yükselten bazı kontrol komut dosyası var.

Ve herhangi bir paylaşılan geliştirici, test ve KG ortamını yalnızca komut dosyalarını uygulayarak ve çalışmazlarsa önceki sürüme geri döndürerek değiştirdiğinizden emin olun, böylece bunları prodüksiyon sırasında serbest bıraktığınızda amaçlandığı şekilde çalışacaklarından emin olabilirsiniz. .

Yeni kurulum basitçe tüm komut dosyaları uygulanarak yapılır. Bir süre sonra, yüzlerce kişiye sahip olabilirsiniz ve bunun çok verimsiz olduğunu düşünebilirsiniz, ancak onu optimize etmeye çalışma tuzağına düşmeyin. Kurulum bir kerelik bir etkinliktir ve onu hızlı kılan güvenilir kozlardır.

@Doc Brown zaten bağlı Martin Fowler: Evrimsel Veritabanı Tasarımı ve /programming/334059/agile-development-and-database-changes ekledim ve Alex Papadimoulis'i ekledim: Veritabanı Değişiklikleri Tamamlandı , daha kısa ve bazı örnekleri var.

Böyle bir süreci uygulayan araçlara iyi bir örnek olarak Alembiç'i öneririm . Python SQLAlchemy çerçevesine dayanır , ancak kendi taşıma destekleri yoksa diğer diller ve çerçevelerle kullanabilirsiniz. Şema Geçişi'ndeki Wikipedia sayfasında bu tür daha fazla araç listelenir .


1
@Tibo, aynı komut dizisini çalıştırarak şemayı sıfırdan oluşturursunuz. Sorunu bu şekilde yönetiyorsunuz. Verilen bu bir standart olarak adreslerden alabilirsiniz herhangi veritabanı örneğinde - güncel şemaya ve aynı olduğunu güven - henüz yok birini dahildir. Örneğinize göre iki yol bulunmasına gerek yoktur. (En azından tutarlı bir taban çizgisi verilmez - ilk adım taban çizgisini oluşturmaktır ve bu taban çizgiye
kalkar

1
Alex'in makalesi için Yaşasın; daha kısa olmayabilir, ancak çok daha pratik odaklı ve eğlenceli bir okuma yapar.
Murphy

1
Biz bir Agile mağazasıyız ve% 100 kesintisiz hizmet veriyoruz ve her ikisi de DB için de geçerli. Üretim şemasını günde ortalama bir kez taşıyoruz ve Jan'ın söylediği her şeyi ikinci yapardım. Yaptığımız bir diğer şey de, geçiş testi olarak adlandırdığımız şeydir; bu, derleme ve dağıtım sürecimizin bir parçası olarak çalışır. Üretimden bir şema anlık görüntüsü alır, master'dan ona bekleyen tüm geçişleri uygular ve sonra o anda dağıtılan üretim kodundan birim testlerini bu şemaya karşı yürütür. Amaç, taşıma işlemlerinin uygulanmasının çalışan sistemi bozmayacağını kontrol etmektir.
Gordon Wrigley

1

İşin tuhafı, şu anki geliştirme ekibimin karşılaştığı sorun. Soru birkaç alt soru içermektedir, bu yüzden bağımsız olarak ele alınacaktır.

Her şeyden önce, ilişkisel bir veritabanı veri modelini çok fazla kısıtlar ve değişiklikleri çok zorlaştırır mı?

Kesinlikle , ancak belirtilen nedenlerden dolayı zorunlu değildir. Ne yazık ki, ilişkisel veritabanı yönetim sistemlerinin çok yönlülüğü de çökmelerine neden olmaktadır. RDBMS başlangıçta büyük veri kümelerini kabul edecek ve bunları nispeten küçük bir boyuta indirecek nispeten basit bir veri depolama platformu sunmak için geliştirilmiştir. Bu, veri modelindeki karmaşıklık ve gerekli hesaplama gücü pahasına yapıldı. Veritabanı karmaşıklığı arttıkça, veritabanı yöneticilerinin karmaşıklıkla tutarlı ve ölçeklenebilir bir şekilde baş etmelerine yardımcı olmak için saklı yordamlar, görünümler, işlevler ve tetikleyiciler ortaya çıkmıştır.

Ne yazık ki, ilişkisel veritabanı modeli nesne yönelimli değildir ve doğal olarak bir veri modelinin olması gerektiği gibi gerçek dünya varlıklarını eşlemez. Bu bizi nesne-ilişkisel haritacılar ve benzerleri gibi aracılara ihtiyaç duymaya yönlendirir. Ne yazık ki, bu araçlar günümüzün gelişim dünyasında açıkça bir yere sahip olsa da, kullanımları sadece veri modelinin gerçek dünyaya yanlış hizalanması olan altta yatan neden yerine ilişkisel veri karmaşıklığı sorununun bir belirtisine yöneliktir.

Bu, sorunun daha çok bir varsayım olduğu, ancak bir soru olarak görülmesi gereken ikinci bölüme yol açar: Alan modelimizi ilk kez doğru yapmamız gerekiyor mu?

Evet, bir dereceye kadar. Sorunun da işaret ettiği gibi, tasarım sürecine başladığımızda sorunu tam olarak anlamak nadiren mümkündür. Bununla birlikte, etki alanını daha iyi anladığımızda değiştirilebilecek olanın aksine, tamamen yanlış bir veri modeli arasındaki fark, gerçek dünyayla tutarlı bir şekilde eşleşen modeldir. Bu, sorunu gerçek dünyadaki varlıkları açısından anlamamızla tutarlı bir başlangıç ​​veri modeli oluşturmak için her türlü çabayı göstermemiz gerektiği anlamına gelir. Yanlış varlıklar üzerinde normalleşmeye başlarsak, veri modeli iki şekilde yanlış olur ve kurtarma zorlaşır.

Birçok yönden, "SQL Yok" veritabanı çözümlerine geçiş, veri modeli tutarsızlığı sorunlarının bir sonucudur. Nesne yönelimli bir SQL yaklaşımı kullanmamak, koddaki nesnelerimizle gerçek dünyadakiler arasındaki eşleme hakkında daha fazla düşünmemize neden olur ve tutarsızlık yaşadığımızda, bu genellikle kendiliğinden belirgindir, çünkü veri tabanı. Bu, daha iyi bir genel tasarıma yol açar.

Bu son soruya götürür: ilişkisel bir veri modeli çevik yaklaşımla tutarsız mıdır?

Hayır, ama daha fazla beceri gerekiyor. No-SQL dünyasında, bir alan eklemek veya bir özelliği bir diziye dönüştürmek önemsiz olsa da, bu şeyleri ilişkisel dünyada yapmak hiç de önemsiz değildir. En azından hem ilişkisel veri modelini hem de temsil ettikleri gerçek dünya varlıklarını anlayabilen birini alır. Bu kişi, gerçek dünya modeli değiştikçe ilişkisel modeli güncellemeyi kolaylaştıracak kişidir. Bu sorunu çözecek gümüş kurşun yok.


1
İfadeyi daha dramatik hale getirmek için RDBMS tablosunda yeni bir alan oluşturma problemini gerçekten umduğunuzu umuyorum. Bir alan eklemek için gerçekten sorun yaratmak için veritabanı tablosunun çok özel olması gerekir (veya yeni alan türünün istisnai bir şey olması gerekir).
Alexey Zimarev

Evet, ama asla sadece bir alan ...
theMayer

1
Daha sık söyleyebilirim ki bu sadece bir alan. Dramatik şema değişiklikleri o kadar sık ​​değildir. Empedans uyumsuzluğu nedeniyle OO tasarımı ile RDBMSes kullanma hayranı değilim. Bununla birlikte, yeni türler (tablolar) ve özellikler (sütunlar) eklemek her iki dünyada nispeten kolaydır, ancak NoSQL'de gerçekten biraz daha kolaydır. Ancak karmaşık değişiklikler her iki durumda da ağrıdır. Daha da kötüsü, anlık görüntüler içeren olay kaynaklı sistemde, bu sistem için geliştirme deneyiminin ne kadar zevkli olduğunun tersine dönüşüyor.
Alexey Zimarev

İlişkisel veritabanlarının veri depolama ihtiyaçlarını çözmek için genellikle "evrensel çekiç" olarak kullanıldığını görüyorum - aslında bunları kullanmak için çok özel nedenler olduğunda. Dikkatle düşünülmüş bir sistemde, cevabımda yazdığım konular hakkında nadiren endişelenmek gerekir - ön tarafta uygun bir sistem tasarımına ulaşma deneyimi olmayan daha genel bir kitleye hitap ediyorum.
theMayer

İlişkisel model arasında bir tutarsızlık yoktur ve genellikle gerçek dünyaya olduğu gibi başka herhangi bir modelle de eşleşir. Bazı işlemler bir tür, diğeri diğer türlerle daha kolay olacaktır. Sorun, bir tür (nesne yönelimli) bir model oluşturduğunuzda ve bunu başka bir tür (ilişkisel) araçlarla uygulamaya çalıştığınızdadır. Bu iyi çalışmıyor. Ancak gerçek dünya nesne yönelimli değildir. Sadece öyle ve sen modellen. Ve seçilen model için doğru araçları kullanmak zorundasınız.
Jan Hudec

-1

Ana nokta, modelinizin tüm tanınmanın ötesinde değişeceği kadar çok yeniden düzenleme yapmak değildir. Yinelemeli gelişmeyle bile, mevcut şeylerin üzerine inşa edilmeli ve parçalara dönüştürülmemelisiniz.

Bu, büyük değişiklikleri geldiklerinde ele almanız için 2 ana seçenek sunar: ilki DB katmanını bir API olarak oluşturmak, saklı yordamları kullanmak, böylece temel veri şemasını değiştirmeden istemciye uyacak şekilde değiştirilebilir.

Diğer yol, tabloları biraz veri taşıma ile değiştirmektir. Büyük ölçekli bir değişiklik gerektiğinde, yeni şemayı oluşturursunuz ve eski verileri alıp yeni formata masaj yapmak için bir dizi komut dosyası uygularsınız. Bunu yapmak zaman alır, bu yüzden ilk seçenek olarak verilere erişimi (örneğin SP'ler aracılığıyla) değiştirmek için daha ucuz yöntemlere daha fazla güvenirsiniz.

Yani: 1. şeyleri değiştirmek gerekmez böylece tasarım ile ileri düşünmeye çalışın.

  1. Değişikliklerin sınırlı olması veya yalıtılmış bir bileşenin içinde gizlenebilmesi için sarmalayıcılara veya API'lara güvenin

  2. Gerekirse doğru şekilde yükseltmek için zaman ayırın.

Bu adımlar sadece veritabanları için değil, her şey için geçerlidir.


Altında yatan düzeni bazen ihtiyacı değiştirilmesi. Uygulama müşteri testine girerken, daha önce hiç duymadığınız yeni özellikler ortaya çıkıyor, sayıların dizeler olduğunu düşündüğünüz özellikler, 1: 1 olması beklenen ilişkiler sonuçta böyle olmamalı. Saklı yordamların arkasındaki bu tür şeyleri kapatamazsınız (ayrıca, saklı yordamlar sorunun bir parçasıdır, çünkü veritabanındaki diğer şeyler gibi, sürüm denetiminde yaşamazlar).
Jan Hudec

@JanHudec SP'ler ne zamandan beri sürüm denetiminde yaşamıyor? Bu tür şeyleri kapsayabilir, bir dizeyi alıp farklı bir alana yazmak için SP API'sini değiştirebilir, eski sayıları ve yeni dizeleri SP'nizdeki kodda biraz tutabilirsiniz. En güzel değil, ancak verilerini yeni dize biçimine taşımak için her müşteri sitesine gitmekten daha iyi olabilir (daha iyi örnekler vardır, ancak fikri anlarsınız). Değişikliğin büyük olduğu ortaya çıkarsa, taşımanız gerekir, ancak en azından bir DB API ile başka, daha ucuz seçenekleriniz de vardır.
16:26

SP'yi yüklemek ve yeni alanı eklemek için hala her müşteri sitesine gitmeniz gerekir. Ve orada olduğunuzda, verileri de taşıyabilirsiniz. SP'ler veritabanına erişen birden fazla uygulamanız varsa geriye dönük uyumlu arabirim oluşturmanıza izin vermeleri açısından faydalıdır, bu nedenle hepsini aynı anda yükseltmeniz gerekmez. Ancak şemanın değişen gereksinimler nedeniyle değişmesi gerektiğinde herhangi bir adım kaydetmezler.
Jan Hudec
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.