Veri doğrulamayı destekleyen bir ORM için, kısıtlamalar veritabanında da uygulanmalıdır mı?


13

(ActiveRecord) modellerime ek olarak her zaman veritabanı düzeyinde kısıtlamalar uyguladım. Ama bunun gerçekten gerekli olup olmadığını merak ediyordum?

Biraz arka plan

Son zamanlarda bir model için temel otomatik zaman damgası oluşturma yöntemini birim test etmek zorunda kaldım. Test normalde modelin bir örneğini oluşturur ve doğrulama yapmadan kaydeder. Ancak tablo tanımında nullable olmayan diğer zorunlu alanlar vardır, yani ActiveRecord doğrulamasını atlasam bile örneği kaydedemiyorum. Bu yüzden db'nin kendisinden bu tür kısıtlamaları kaldırmalı mıyım ve ORM'in bunları ele almasına izin vermeli miyim diye düşünüyorum.

Db, imo kısıtlamalarını atlarsam olası avantajlar -

  • Veritabanını taşımak zorunda kalmadan modeldeki bir doğrulama kuralını değiştirebilir.
  • Testte doğrulamayı atlayabilir.

Olası dezavantaj?

ORM doğrulamasının başarısız olması veya atlanması olası ise, veritabanı kısıtlamaları denetlemez.

Ne düşünüyorsun?

DÜZENLEME Bu durumda, veritabanından modeli üreten Yii Framework kullanıyorum , bu nedenle veritabanı kuralları da oluşturulur (gerçi onları her zaman post-nesil kendim de yazabilirsiniz).


3
Veritabanınızdaki veriler, ORM'nizi (ORM'niz olmayan diğer uygulamalar veya daha da kötüsü, kullanıcılar tarafından doğrudan db erişimi) kullanmadan rutin olarak değiştirilebilirse, doğrulamanın gerçekten veritabanında olması gerekir.
Marjan Venema

Yanıtlar:


16

Yol gösterici ilkeniz Kendinizi Tekrarlamayın :

Yazılım mühendisliğinde, Kendini Tekrar Etmeyin (DRY), özellikle çok katmanlı mimarilerde faydalı olan her türlü bilginin tekrarını azaltmayı amaçlayan bir yazılım geliştirme ilkesidir. KURU ilkesi "Her bilgi parçasının bir sistem içinde tek, açık, yetkili bir temsili olması gerekir" şeklinde ifade edilir.

ORM esasen, uygulamanız ve veri depolamalarınız arasında rahatça oturan ekstra bir katman (veya isterseniz katman). Kısıtlamalarınız, ORM veya veri depolama alanı olsun, tek bir yerde ve yalnızca bir yerde olmalıdır , aksi takdirde kısa süre içinde farklı sürümlerini kullanmaya devam edersiniz. Bunu gerçekten yapmak istemiyorsun.

Bununla birlikte, pratikte, yarı iyi ORM'lerin çoğu, veri şemanızdan otomatik olarak çok sayıda model üretir. Yine de çoğaltma olmasına rağmen, çoğaltılan ORM kodu her seferinde aynı desen izlenerek üretildiğinden bakım cehennemi olasılığı minimumdur. Yinelenen kod olmaması idealdir, ancak otomatik olarak oluşturulan kısıtlamalar bir sonraki en iyi şeydir.

Ayrıca, kısıtlamalarınızın tek bir yerde bulunması, tüm kısıtlamalarınızın aynı yerde olması gerektiği anlamına gelmez . Referans bütünlüğü kısıtlamaları gibi bazıları veri depolama için daha uygun olabilir (ancak başka bir veri deposuna geçerseniz kaybolabilir) ve bazıları, çoğunlukla karmaşık iş mantığıyla ilgili olanlar ORM'nize daha uygundur. Tüm elmaları aynı sepete koymak tercih edilir, ama…

Hataları

ORM'in başarısız olduğunu söylediniz. Bu, sorunuzla kesinlikle alakasız, uygulamanızın ORM ve veri depolama (lar) ını tek bir varlık olarak düşünmesi gerekir. Başarısız olursa, başarısız oldu, doğrudan veri deposuyla konuşmak için ORM'yi atlamak iyi bir fikir değil .

Başka bir şey için ORM'yi atlamak

Ayrıca iyi bir fikir değil. Bununla birlikte, çeşitli nedenlerle olabilir:

  1. ORM sunulmadan önce oluşturulan uygulamanın eski bölümleri.

    Bu zor bir durum ve tam olarak şu an uğraştığım durum , dolayısıyla sürekli “bakım cehennemi” tekrar ediyorum. ORM olmayan parçaları bakımını yapmaya devam edersiniz veya ORM'yi kullanmak için bunları yeniden yazarsınız. İkinci seçenek başlangıçta daha anlamlı olabilir , ancak bu sadece uygulamanızın tam olarak hangi bölümlerinin ne yaptığını ve uzun vadede tam bir yeniden yazmanın ne kadar değerli olacağına dayanan bir karardır.

    Kötü tasarlanmış 2 * 10 ^ 8 satırlı MySQL tablosundaki bir anahtarı değiştirmeyi deneyin (kesinti olmadan) ve nereden geldiğimi anlayacaksınız.

  2. Uygulamanın, doğrudan veri deposuyla doğrudan konuşması gereken eski olmayan bölümleri:

    Daha hileli bile. ORM'ler süslü araçlardır ve neredeyse her şeyle ilgilenirler, ancak bazen sadece yol alırlar veya hatta kesinlikle işe yaramazlar. Buzzword (gerçekten buzzphrase) nesne-ilişkisel empedans uyuşmazlığıdır , basitçe ORM'inizin ilişkisel veritabanınızın yaptığı her şeyi yapmasının teknik olarak mümkün olmadığını ve yaptıkları bazı şeyler için önemli bir performans cezası olduğunu belirtin.

Yorumlar

Veri bütünlüğü açısından, kısıtlamalar veritabanında OLMALIDIR ve uygulamada OLMALIDIR. Uygulamanıza bir web ve masaüstü uygulamalarından, bir mobil uygulamadan veya bir web hizmetinden erişilirse ne olur? - Luiz Damim

Fazladan bir katman eklemenin son derece yardımcı olacağı yer burası ve eğer bir web uygulaması hakkında konuşursak bir REST API ile giderdim. Bunun için aşırı basit bir tasarım :

resim açıklamasını buraya girin

ORM, API ve veri depoları arasında oturur ve API'nın arkasındaki her şey (dahil) çeşitli uygulamalardan tek bir varlık olarak kabul edilir.


Normalde ORM'nizde daha sonra veritabanına yansıtılan bir şema tanımlarsınız, böylece ikinci bir güvence seviyeniz olur.
Josh K

2
@JoshK İkinci güvence diyorsunuz, ben bakım cehennemi diyorum. Yine de doğru olmadığını söylemiyorum ...
yannis

Mantıklı. Şimdi bu rotayı takip ediyorum. Teşekkürler!
na

1
Bir veya iki geliştiricinin kod ve veritabanı çalışması yaptığı noktayı geçtikten sonra gerekli bir kötülük haline gelir. İyi bir ORM kullanırsanız, sizin için de taşıma oluşturur. Özel bir DBA'ya sahip olduğunuz bir noktaya kadar büyüdüğünüzde, bunun bir yolu yoktur, tabloların herhangi bir kısıtlama olmaksızın yüzmesine izin vermezler. İnsanların e-posta olmadan kaydolmasını önlemenin basit yolu, depolama alanı sınırlaması yapmaktır.
Josh K

1
Veri bütünlüğü açısından, kısıtlamalar veritabanında OLMALIDIR ve uygulamada OLMALIDIR. Uygulamanıza bir web ve masaüstü uygulamalarından, bir mobil uygulamadan veya bir web hizmetinden erişilirse ne olur?
Luiz Damim

20

Bu aslında cevaplaması çok zor bir soru ve bunun çok tartışmalı bir konu olduğunu gördüm.

Yannis Rizos'un cevabında belirttiği gibi, hem veritabanında hem de ORM katmanında kısıtlama mantığına sahip olmak, "bakım kabuslarına, kötü faktoringe ve mantıksal çelişkilere yol açabilecek" DRY'yi ihlal ediyor gibi görünüyor.

Ancak, kısıtlama mantığını veritabanından kaldırmak ve yalnızca ORM katmanında tutmak , aşağıdaki koşullardan herhangi birine sahipseniz çalışmaz:

  1. Manuel DB güncellemeleri (her şirkette gerçekleşiyor gibi görünüyor)

  2. ORM kısıtlama mantığını her zaman kolayca paylaşamayan başka bir sistemden DB güncellemeleri (ORM katmanı Hazırda Bekletme modunda uygulandığında ve bir Java uygulaması tarafından günlük etkinlik için kullanıldığında rutin görevleri gerçekleştiren Perl betiği)

Bu , kısıt mantığını DB'ye eklemenizi ve bir KURU ihlali önlemek için ORM katmanınızdan kaldırmanızı önerir . Bununla birlikte, bu, uygulama kodunun gerçek sorunu başarıyla yakalayamadığı ve kullanıcıya geçemediği durumlara yol açabilir (ancak bir geliştirici sorunun hatalarını ayıklamak için büyük olasılıkla yapabilirsiniz). Bu, bazı projeler için kabul edilemeyebilir.

Son seçeneğiniz, DB kısıtlamalarından ORM'de (ve diğer herhangi bir sistemde) kısıtlamaların oluşturulmasını otomatikleştirmektir (veya tam tersi). Sonunda, kısıtlamaların iki veya daha fazla uygulanmasına rağmen, DRY ihlallerinden kaçınmak için kod oluşturmanın kullanılmasını önerdikleri için "Pragmatik Programcı" da açıklandığı gibi DRY ilkesinin ihlali olmayacaktır. Tabii ki, bu kadar basit değil, örneğin, bir DB kısıtlamasındaki her değişiklik, onu kullanan tüm uygulamalarınızın yeniden oluşturulmasını ve yeniden konuşlandırılmasını zorlayabilir (otomatikleştirmek için önemsiz değildir).

Gerçekten, durum bazında değerlendirilmelidir . Bu noktaya kadar, kısıtlama mantığının tekrarlanmamasını önerdiğimde boş bakışlarla karşılaşıldığımı söyleyebilirim.


2
İşten yeni çıktım ve yanıtımı az önce yayınladığınız şey olarak genişletmeyi düşünüyordum. İyi cevap!
yannis

3

Kesinlikle benim varsayılan seçenek olarak veritabanına kısıtlamalar eklemek istiyorum. Bunun nedeni, bir işletme için verilerin kraldır ve veri kalitesinin çok önemli olmasıdır. @Yannis Rizos, KURU prensibini tartışmaya getirdi. Başka bir ilke Derinlikte Savunma. Veri için bu prensibi kullanırdım.

DB'nin 30 yıl önce veri oluşturduğu gerçek işletmelerde çalıştım. COBOL uygulaması ve şimdi bir .Net uygulaması tarafından erişildi ve hala erişilebilir. 10 yıl içinde bunu bilen bir satıcı uygulaması olabilir. Birleşme oldu ve milyonlarca veri satırı SQL kullanılarak diğer şirketten bu veritabanına dönüştürüldü ve taşındı. Hiçbir ORM bunu yapamaz. Alt satırda Veri kalır, uygulamalar değişir, Verilerin oluşturulma şekli değişir. Öyleyse neden veri bozulması olasılığını azaltmıyorsunuz?


2

Her ikisini de bir dereceye kadar yaptığınızı düşünüyorum.

  • Birincil kısıtlamalar ORM'de yaşamalıdır - programlama dilleri çok daha esnektir, gereksinimler değiştiğinde test edilmesi ve ayarlanması daha kolaydır; DDL düzeltmeleri konusunda endişelenmenize gerek yok. Ve genellikle veri regresyon sorunlarını test etmekte zorlanırsınız.

  • Bazı çok zor ve hızlı kısıtlamalar da veritabanında yaşamalıdır. Mesela null olmayan isimlerden bahsetmiyorum. Referans bütünlüğü veya kesinlikle çok önemli tanımlayıcılar gerektirme gibi şeylerden bahsediyorum. Yapısal gereklilikler, bu nedenle kodunuzun "Siparişte var olmayan bir ürün varsa" ilgilenmesi gerekmez.


1

DRY'nin ihlal edilebildiği tek yer veritabanı IMO'dur, çünkü bir şey ORM'nizi atlar ve kötü verilere sahipse, işte budur. Oyun bitti. Bozuk veriye sahip olmak öldürücü darbe.


Yalnızca veritabanı? Verilerle ilgili davranışların, veriler hiç kalıcı olmasa bile, birkaç katmanda (mantıksal veya fiziksel) bulunması gereken birçok durumu düşünebilirim. Bazen tek bir kaynak kodu olması ve dağıtılan dll en "çoğaltma" azaltmak mümkündür.
mike30
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.