Veritabanındaki hatalı null girişlere karşı koruma sağlayan tasarımlar ve uygulamalar


9

Programımın bir kısmı, veritabanımdaki birçok tablo ve sütundaki verileri işlenmek üzere alıyor. Sütunlardan bazıları olabilir null, ancak geçerli işleme bağlamında bu bir hatadır.

Bu "teorik olarak" olmamalıdır, bu yüzden eğer kötü veriler veya koddaki bir hataya işaret eder. Hangi alanın olduğuna bağlı olarak hataların farklı önem dereceleri vardır null; yani bazı alanlar için işlem durdurulmalı ve birileri bilgilendirilmeli, bazıları için işlemenin devam etmesine ve birisini bilgilendirmesine izin verilmelidir.

Nadir fakat olası nullgirişleri ele alacak iyi bir mimari veya tasarım ilkesi var mı?

Çözümlerin Java ile uygulanması mümkün olmalı, ancak etiketi kullanmadım çünkü sorunun biraz dil bilincine sahip olmadığını düşünüyorum.


Kendime sahip olduğum bazı düşünceler:

NOT NULL kullanma

En kolay veritabanında NOT NULL kısıtlaması kullanmak olacaktır.

Peki ya verilerin orijinal olarak eklenmesi bu sonraki işlem adımından daha önemli ise? Bu yüzden eklenti nulltabloya bir hata koyarsa (hatalar veya belki de geçerli bir sebepten dolayı), ekin başarısız olmasını istemem. Programın daha birçok bölümünün eklenen verilere bağlı olduğunu ancak bu sütuna bağlı olmadığını varsayalım. Bu nedenle, ekleme adımı yerine geçerli işlem adımında hata riskini tercih ederim. Bu yüzden NOT NULL kısıtlaması kullanmak istemiyorum.

Saf olarak NullPointerException özelliğine bağlı

Verileri her zaman orada olmasını beklediğim gibi kullanabilirim (ve bu gerçekten böyle olmalı) ve ortaya çıkan NPE'leri uygun bir seviyede yakalayabilirim (örneğin, mevcut girişin işlenmesi durur, ancak tüm işleme ilerlemesi değil) ). Bu "hızlı başarısız" ilkesi ve ben sık sık tercih ederim. En azından bir hata ise, kayıtlı bir NPE alırım.

Ama sonra çeşitli eksik veri türlerini ayırt etme yeteneğini kaybediyorum. Örneğin, bazı eksik veriler için veriyi dışarıda bırakabilirim, ancak diğerleri için işlem durdurulmalı ve bir yönetici bilgilendirilmelidir.

nullHer erişimden önce kontrol etme ve özel istisnalar atma

Özel istisnalar, istisnayı temel alarak doğru eyleme karar vermeme izin verecek, bu yüzden bu yol gibi görünüyor.

Ama bir yerde kontrol etmeyi unutursam ne olur? Ayrıca daha sonra asla veya nadiren beklenen null çekler ile kod dağınıklığı (ve kesinlikle iş mantık akışının bir parçası değil).

Bu şekilde gitmeyi seçersem, yaklaşım için hangi modeller en uygunudur?


Yaklaşımlarım ile ilgili her türlü düşünce ve yorumlarınızı bekliyoruz. Ayrıca her türlü daha iyi çözümler (kalıplar, ilkeler, kodumun daha iyi mimarisi veya modelleri vb.).

Düzenle:

Başka bir kısıtlama var, ben bir ORM DB kalıcılık nesnesine eşleme yapmak için kullanıyorum, bu nedenle bu düzeyde null kontrolleri yapmak işe yaramaz (null herhangi bir zarar vermediği yerlerde aynı nesneler kullanılır gibi) . Bunu ekledim çünkü şimdiye kadar verilen cevaplar bu seçenekten bahsetti.


5
"Sütunlardan bazıları boş olabilir, ancak geçerli işleme bağlamında bir hata bu. ... ekleme, tabloya boş bırakacaksa, eklemenin başarısız olmasını istemem." Bu iki gereksinim çelişkili. Bu var imkansız iki koşullardan birini dinlenmek kadar bir çözüm bulmak için.
Kilian Foth

@KilianFoth Benim rahatlığım, "mevcut işleme" bağlamındaki hatanın yerleştirme işleminden daha az şiddetli olmasıdır. Bu nedenle, nadir işleme hatalarını kabul ediyorum, ancak bunları ele almak için iyi bir sağlam tasarıma sahip olmak istiyorum. Bu nedenle, aksi takdirde iyi bir çözüm olabilecek NOT NULL, burada mümkün değildir.
jhyot

1
Çok fazla hatayı kabul etmeye devam ederseniz, bu hataların yaratıcıları onları asla düzeltemez. Dağınık uç ifadeleri başarılı olursa, işleri düzeltmek için ne gibi teşvikler gerekir? Sağlamın başarısız değil, kötü veri kabul ettiğini düşünüyor musunuz?
Tulains Córdova

@ user61852 Hataları açıkça kabul etmiyorum ancak bunları incelikle işlemek istiyorum. Boş göstergeleri yutmak söz konusu değildir. Ayrıca, parçamın gerçekten (nesnel olarak tanımlandığı gibi), objektifin başarılı olmasını gerektiren ancak bu alanın ayarlanmasını gerektirmeyen diğer birçok parçadan daha az önemli olması durumunda ne olur? Ekler, değer eklemeye zorlayabileceğim bir kullanıcı girişinden değil, ihmalin büyük olasılıkla bir hata olduğu (ancak eki kıracak kadar önemli olmayan) diğer koddan kaynaklanır.
jhyot

1
Bunları veritabanında NULL DEĞİL olarak işaretlemek en iyi çözüm olacaktır, eğer bir sütun boş bırakılabilirse, kodun beklendiği durumda, beklemese bile, depolama mekanizması izin verdiği için durumu işlemesi gerekir.
Jon Raynor

Yanıtlar:


9

Nesnenizi sonuç kümesinden oluşturduğunuz eşleme kodunuza null kontrolleri koyacağım. Bu, denetimi tek bir yere koyar ve bir hataya çarpmadan önce kodunuzun bir kaydı işleyerek yarıya inmesine izin vermez. Uygulama akışınızın nasıl çalıştığına bağlı olarak, her bir kaydın tek tek eşlenmesi ve işlenmesi yerine tüm sonuçların eşlenmesini bir ön işleme adımı olarak gerçekleştirmek isteyebilirsiniz.

Bir ORM kullanıyorsanız, her kaydı işlemeden önce tüm boş denetimlerinizi yapmanız gerekir. Ben recordIsValid(recordData)-type yöntemi tavsiye ederim , bu şekilde (tekrar) tüm null kontrol ve diğer doğrulama mantığını tek bir yerde tutabilirsiniz. Boş kontrolleri işleme mantığınızın geri kalanıyla kesinlikle karıştırmam.


Teşekkürler, bu iyi bir fikir! Ben gerçekten bir ORM kullanıyorum, bu yüzden bu seviyede kontroller işe yaramaz. Ama aynı zamanda kalıcılık nesnelerinden gerçek etki alanı nesnelerine eşleme var. Bir ön işleme adımında haritalama ve doğrulamanın mümkün olup olmadığını kontrol edeceğim.
jhyot

Eğer ORM'nizi değiştirirseniz, o zaman ne olacak? Bunu kaynağında savunmak daha iyidir (Doc Brown'ın cevabına bakınız).
Robbie Dee

@RobbieDee: Önemli değil. Eşleme kodunu yeniden yazmanız gerekiyorsa, boş denetimler oradadır ve bunları yeniden yazma işleminin bir parçası olarak değiştirirsiniz veya iş nesnelerinizde boş denetimler gerçekleştiren ayrı bir yönteminiz vardır, bu nedenle yeniden yazma gerekmez. Doc Brown'un da ifade ettiği gibi, bazen bu gerçeği varsayılan bir değerle parlatmak yerine verilerin eksik olduğunu fark etmek önemlidir.
TMN

Bu, ETL akışında daha da ileri gitmelidir. Hala bu şekilde çaba sarf etme riskiyle karşı karşıyasınız.
Robbie Dee

6

Bir boş değer eklemek hata gibi görünüyor, ancak veri kaybetmek istemediğiniz için bu hatayı ekleme işleminde uygulamaktan korkuyorsunuz. Ancak, bir alan boş olmamalı, ancak boşsa veri kaybediyorsunuzdur . Bu nedenle, en iyi çözüm null alanların yanlışlıkla kaydedilmemesini sağlamaktır.

Bu amaçla, söz konusu veri, veritabanı için bir yetkili, kalıcı depoda verilerin doğru olmasını sağlayın. Boş olmayan kısıtlamalar ekleyerek bunu yapın. Daha sonra kodunuz başarısız olabilir, ancak bu hatalar sizi hemen hatalardan haberdar ederek, veri kaybetmenize neden olan sorunları düzeltmenizi sağlar. Artık hataları kolayca belirleyebildiğinize göre, kodunuzu ve iki kez test edebilirsiniz . Veri kaybına yol açan hataları düzeltebileceksiniz ve bu süreçte, verilerin aşağıya doğru işlenmesini büyük ölçüde basitleştireceksiniz, çünkü null'lar için endişelenmenize gerek kalmayacak.


2
Cevap için teşekkürler. Çözümünüzün bunu yapmanın doğru yolu olduğunu kabul ediyorum ve özlü bir şekilde ifade ettiniz. Etkim dışındaki kısıtlamalar zor veya imkansız hale getirebilir (örneğin, test etmek veya mevcut kodu otomatik olarak test edilebilir yapmak için mevcut olmayan kaynaklar), ancak bu çözümün diğer yolları denemeden önce çalışıp çalışmadığını kesinlikle iki kez kontrol etmeliyim. Orijinal düşüncemde, sorunu çok hızlı bir şekilde çözebilirim ki, sorunu kaynağında çözemem.
jhyot

@jhyot Tamam. İşleri temiz şekilde yapamadığınızda sinir bozucu oluyor. Umarım cevabım en azından benzer problemleri olan ancak gerçekten sonra karışıklığı temizlemek yerine kök nedene saldırabilenler için yararlıdır.
Monica

5

Sorudaki bu cümle ile ilgili olarak:

Bu "teorik olarak" olmamalıdır, bu yüzden eğer kötü veriler veya koddaki bir hataya işaret eder.

Bu alıntıyı her zaman takdir ettim ( bu makalenin izniyle ):

Acemi programcılar ana işlerinin programların çökmesini önlediğine inandıklarında eğlenceli buluyorum. Bu muhteşem başarısızlık argümanının böyle bir programcıya bu kadar çekici gelmeyeceğini düşünüyorum. Daha deneyimli programcılar doğru kodun harika olduğunu, çökmelerin kodunu iyileştirmeyi kullanabileceğini, ancak çökmeyen yanlış kodların korkunç bir kabus olduğunu fark ederler.

Temel olarak: Postel Yasasını onaylıyormuşsunuz gibi geliyor , "gönderdiğiniz şeyde muhafazakar olun, kabul ettiğiniz şeyde liberal olun". Teoride büyük olmakla birlikte, pratikte bu "sağlamlık ilkesi" en azından uzun vadede ve bazen de kısa vadede sağlam olmayan yazılıma yol açmaktadır . ( Çoğunlukla ağ protokolü kullanım vakalarına odaklanmış olsa da, konunun çok kapsamlı bir tedavisi olan Sağlamlık İlkesi Yeniden Düşünülen makalesini karşılaştırın .)

Veritabanınıza yanlış veri ekleyen programlarınız varsa, bu programlar bozuktur ve düzeltilmesi gerekir . Sorun üzerinde kağıtlama sadece daha da kötüleşmeye devam etmesini sağlar; bu, bir bağımlıya bağımlılığını devam ettirme olanağı sağlayan yazılım mühendisliği eşdeğeridir .

Pragmatik olarak konuşmak gerekirse, bazen "kırık" davranışın en azından geçici olarak, özellikle gevşek, kırık bir durumdan katı, doğru bir duruma sorunsuz bir geçişin bir parçası olarak devam etmesini sağlamanız gerekir. Bu durumda, yanlış eklemelerin başarılı olmasına ve "kurallı" veri deposunun her zaman doğru durumda olmasına izin vermenin bir yolunu bulmak istersiniz . Bunu yapmanın çeşitli yolları vardır:

  • Hatalı oluşturulmuş ekleri doğru eklere dönüştürmek için bir veritabanı tetikleyicisi kullanın, örneğin eksik / boş değerleri varsayılanlarla değiştirerek
  • Yanlış programların "yanlış" olmasına izin verilen ayrı bir veritabanı tablosuna eklenmesini sağlayın ve düzeltilmiş verileri bu tablodan standart veri deposuna taşıyan ayrı bir zamanlanmış işleme veya başka bir mekanizmaya sahip olun.
  • Veritabanından alınan verilerin, beklemedeki veriler olmasa bile her zaman doğru durumda olduğundan emin olmak için sorgu tarafı filtrelemesi (örn. Bir görünüm) kullanın

Tüm bu sorunları ortadan kaldırmanın bir yolu, yazma sorunları ve gerçek veritabanı arasında kontrol ettiğiniz bir API katmanı eklemektir.

Sorununuzun bir parçası gibi görünüyor, yanlış yazma oluşturan tüm yerleri bile bilmiyorsunuz - ya da güncellemeniz için çok fazla şey var. İçinde olmak korkunç bir durum, ama ilk etapta ortaya çıkmasına asla izin verilmemeliydi.

Kanonik bir üretim veri deposundaki verileri değiştirmesine izin verilen birkaç sistemden daha fazlasını alır almaz başınız derde girer: bu veritabanı hakkında merkezi bir şey tutmanın hiçbir yolu yoktur . Daha iyisi, yazma işlemlerini mümkün olduğunca az sayıda işleme izin vermek ve bunları gerekli şekilde eklemeden önce verileri önceden işleyebilen "ağ geçidi denetçileri" olarak kullanmaktır. Bunun kesin mekanizması gerçekten sizin mimarinize bağlıdır.


"Veritabanınıza yanlış veri ekleyen programlarınız varsa, bu programlar bozuktur ve düzeltilmesi gerekir." teoride de bu harika, ama gerçekte hala bazı kayıtlar "NA" veya "Hiçbiri" kullanılıp kullanılmayacağı konusunda tartışmaya devam ederken kayıtlar ekleyecekler.
JeffO

@JeffO: Hiçbir komite "NA", "Hiçbiri", NULL veya veritabanında başka bir şey depolayıp saklamayacağını tartışmamalıdır . Teknik olmayan paydaşlar veri gelir ne menfaatine olacaktır dışarı veritabanının ve nasıl ama iç temsilinde kullanılır.
Daniel Pryden

@DanielPryden: Son işimde, web alanları arası teknik değişiklikleri inceleyecek bir Mimari İnceleme Kurulumuz vardı (DBA alt komitesiyle birlikte). Çok teknik, ama sadece iki haftada bir tanıştılar ve eğer onlar için yeterli ayrıntı vermediyseniz, bir sonraki toplantıda ... bir karar verene kadar ertelediler. Yeni kod aracılığıyla işlevsellik eklemekten ibaret olmayan önemsiz sistem değişikliklerinin çoğu rutin olarak bir ay kadar sürer.
TMN

@DanielPryden - Metin kutusu etiketlerinde üst yönetim tartışması ile toplantılarda oturdum. Bunun, uygulamada veya veritabanında adlandıracağınız şeyle ilgisi olmadığını iddia edebilirsiniz, ancak öyle.
JeffO

Bu tür değişiklikler için ek onaylar almayla ilgili yorumlara yanıt olarak: "yanlış" değerler hakkındaki düşüncem, izin verilen değerlerin zaten bir yerde belgelendiğini varsayar - bu yüzden OP bu değerlerin bir hata olarak görülmesi gerektiğini söyler. Veritabanının şeması bir değere izin verecek şekilde belirtilirse, bu değer bir hata değildir. Mesele şudur, şemanızla eşleşmeyen verileriniz varsa, bir şey bozulur: Önceliğiniz verilerin ve şemanın eşleşmesi olmalıdır. Takıma bağlı olarak, verilerin, şemanın veya her ikisinin değiştirilmesini içerebilir.
Daniel Pryden

2

" Nadir ama olası null girdileri ele almak için iyi mimari veya tasarım ilkeleri var mı? "

Basit cevap - evet.

ETL

Verilerin veritabanına girmek için yeterli kalitede olmasını sağlamak için bazı ön işlemleri gerçekleştirin. Bırakma dosyasındaki her şey geri bildirilmeli ve tüm temiz veriler veritabanına yüklenebilir.

Hem kaçak avcı (dev) hem de oyun kaleci (DBA) olan biri olarak, acı deneyimlerden, 3. tarafların zorlanmadıkça veri sorunlarını çözmeyeceğini biliyorum. Sürekli geriye doğru eğilme ve verilere masaj yapma tehlikeli bir emsal oluşturur.

Mart / Depo

Bu senaryoda, ham veriler depo DB'sine aktarılır ve daha sonra sanitize edilmiş bir sürüm, uygulamaların erişebileceği mart DB'ye aktarılır.

Varsayılan değerler

Sütunlara varsayılan varsayılan değerleri uygulayabiliyorsanız, bu, varolan bir veritabanı ise, bazı işleri içerebilir.

Erken başarısız

Sadece uygulama, rapor paketi, arayüz vb. Ağ geçidindeki veri sorunlarını ele almak caziptir. Sadece buna güvenmemenizi şiddetle tavsiye ederim. DB'ye başka bir widget'ı bağlarsanız, muhtemelen aynı sorunlarla tekrar karşılaşırsınız. Veri kalitesi sorunlarını giderin.


+1 Yaptığım şey bu, tüm verileri toplamak ve uygulamanızın işlemesi için geçerli bir veri kümesi oluşturmak.
Kwebble

1

Kullanım durumunuz NULL değerini güvenli bir şekilde iyi bir varsayılan değerle değiştirmeye izin verdiğinde, dönüştürmeyi SELECTSql deyimlerinde ISNULLveya kullanarak yapabilirsiniz COALESCE. Yani yerine

 SELECT MyColumn FROM MyTable

biri yazabilir

 SELECT ISNULL(MyColumn,DefaultValueForMyColumn) FROM MyTable

Tabii ki, bu sadece ORM doğrudan select deyimlerini doğrudan değiştirmeye izin verirse veya nesil için değiştirilebilir şablonlar sağlarsa işe yarar. Bu şekilde hiçbir "gerçek" hatanın maskelenmediğinden emin olunmalıdır, bu yüzden yalnızca NULL durumunda varsayılan değerle değiştirmek tam olarak istediğiniz şeyse uygulayın.

Veritabanını ve şemayı değiştirebiliyorsanız ve db sisteminiz bunu destekliyorsa, @RobbieDee tarafından önerilen şekilde belirli sütunlara varsayılan bir değer cümlesi eklemeyi düşünebilirsiniz. Bununla birlikte, bu, daha önce girilen NULL değerleri kaldırmak için veritabanındaki mevcut verilerin de değiştirilmesini gerektirir ve daha sonra doğru ve eksik içe aktarma verilerini ayırt etme yeteneğini ortadan kaldırır.

Kendi tecrübelerime göre, ISNULL kullanmanın şaşırtıcı derecede iyi çalışabileceğini biliyorum - geçmişte orijinal geliştiricilerin çok sayıda sütuna NOT NULL kısıtlamaları eklemeyi unuttuğu eski bir uygulamayı sürdürmek zorunda kaldım ve bu kısıtlamaları daha sonra kolayca ekleyemedik bazı nedenlerden dolayı. Ancak tüm vakaların% 99'unda, sayı sütunları için varsayılan olarak 0 ve metin sütunları için varsayılan olarak boş dize tamamen kabul edilebilirdi.


Bu çalışırken, her SELECT için savunma kodunu çoğaltmak zorunda kalabilirsiniz. Çok daha iyi bir yaklaşım, bir NULL yerleştirildiğinde bir sütun için varsayılan bir değer tanımlamaktır, ancak bu çeşitli nedenlerle mümkün olmayabilir / istenemez.
Robbie Dee

@RobbieDee: Bu açıklama için teşekkürler, cevabımı buna göre değiştirdim. Ancak, bu "çok daha iyi" ise tartışmalıdır. CRUD kodu bir yerde olduğunda, yinelenen savunma kodu çok fazla sorun teşkil etmeyebilir. Ve değilse, önceden bazı kod çoğalmaları var.
Doc Brown

Basit CRUD operasyonları elbette idealdir. Ancak gerçek dünyada, sistemler genellikle karmaşık kullanıcı arayüzü görünümlerine, kullanıcı tarafından oluşturulan veri sihirbazlarına, raporlara vb. Sahiptir. Açıkladığınız şey bir kahverengi alan gelişiminde tercih edilebilir.
Robbie Dee

En iyi cevap. Yeni uygulamalar genellikle kontrolünüz dışında olabilecek bazı yeni veriler ekler. Hatalı NULL'lar genellikle eski verileri yeniden tasarlanan veritabanlarına aktarır. Bunun birkaç gün yerine birkaç saat içinde tamamlanabilmesi için kısıtlamalar kapatılmıştır. "Büyük başarısızlık" genellikle DBA'lar kısıtlamaları yeniden etkinleştirmeye çalıştıklarında gelir. Daha önce hiç planlanmadığı için, yönetim genellikle kötü verileri düzeltmek için sıklıkla gerekli olan haftalar süren işlerde başı çeker. Tüm uygulamalar, varsayılanları ekleyerek ve eksik verileri bildirerek veya istemeyi isteyerek NULL'ları zarif bir şekilde işlemelidir.
DocSalvager

1

OP, iş kurallarını veritabanı teknik detayları ile birleştiren bir cevap varsaymaktadır.

Bu "teorik olarak" olmamalıdır, bu yüzden eğer kötü veriler veya koddaki bir hataya işaret eder. Hangi alanın boş olduğuna bağlı olarak hataların farklı önem dereceleri vardır; yani bazı alanlar için işlem durdurulmalı ve birileri bilgilendirilmeli, bazıları için işlemenin devam etmesine ve birisini bilgilendirmesine izin verilmelidir.

Tüm iş kuralları bu. İş kuralları null per se umurumda değil. Her şey için veritabanı null, 9999, "BOO!" ... sadece başka bir değer. Bir RDBMS'de, null'un ilginç özellikleri vardır ve benzersiz kullanımları tartışmalıdır.

Önemli olan tek şey, "işsizliğin" verilen iş nesneleri için ne anlama geldiğidir ...

Nadir ama olası null girdileri ele almak için iyi bir mimari veya tasarım ilkesi var mı?

Evet.

  • İş kurallarını sınıflara koyun.
  • Harf çevirisi, iş sınıflarını ve veri deposunu ayıran uygun bir kod katmanında olmalıdır. ORM koduna koyamazsanız en azından veritabanına koymayın.
  • Veritabanını olabildiğince aptal hale getirin, burada iş kuralları yok. Bir değeri varsayılan etmek gibi zararsız şeyler bile sizi ısıracaktır . Orada bulunmak.
  • Veritabanına giden ve veritabanından gelen verileri doğrulayın. Ve elbette bu, iş nesneleri bağlamında yapılır.

Veri alımı üzerine bir istisna atmak mantıklı değildir.

Soru "kötü" verileri saklamalı mıyım? " Değişir:

  • Hatalı veriler kullanılabilir - Asla geçersiz nesneleri veya nesne kompozitlerini kaydetmeyin. Her yerde karmaşık veri / iş ilişkileri. Kullanıcılar, istedikleri zaman herhangi bir işlevi yerine getirebilir, muhtemelen bu ticari varlığı bir dizi bağlamda kullanabilirler. Kötü verilerin, kaydedildiği andaki etkisi (eğer varsa), gelecekteki kullanıma büyük ölçüde bağımlı olduğu için bilinmemektedir. Bu verilerin birleştirilmiş / tek bir işlemi yoktur.
  • Kötü veri varsa ilerleme kaydedilemez - Kötü verilerin kaydedilmesine izin ver. Ancak, bir süreçteki bir sonraki adım her şey geçerli olana kadar devam edemez. Örneğin gelir vergisi yapmak. Veritabanından alındığında yazılım hataları gösterir ve geçerlilik kontrolü yapılmadan IRS'ye gönderilemez.

0

Boş değerleri işlemenin birçok yolu vardır, bu nedenle veritabanı katmanından uygulama katmanına geçeceğiz.


Veritabanı katmanı

Sen edebilirsiniz boş değerlere korusun ; burada olmasına rağmen pratik değildir.

Sen edebilirsiniz varsayılan yapılandırmak başına kolon bazında:

  • sütunun olmaması gerekir insert, bu nedenle açık null yerleştirmeyi kapsamaz
  • insertbu sütunu yanlışlıkla kaçırdığı satırlardan algılamayı önler

Sen edebilir bir tetikleyici yapılandırmak sokulması üzerine kayıp değerleri otomatik olarak hesaplanır böylece,:

  • bu hesaplamayı gerçekleştirmek için gerekli bilgilerin mevcut olmasını gerektirir
  • yavaşlayacak insert

Sorgu katmanı

Sen edebilirsiniz satırları atlamak uygunsuz bir yerde nullbulunur:

  • ana mantığı basitleştirir
  • "kötü satırların" algılanmasını önler, bu nedenle bunları kontrol etmek için başka bir işlem gerekir
  • her bir sorgunun araçsal olarak kullanılmasını gerektirir

Sen edebilirsiniz varsayılan bir değer sağlamak sorguda:

  • ana mantığı basitleştirir
  • "kötü satırların" algılanmasını önler, bu nedenle bunları kontrol etmek için başka bir işlem gerekir
  • her bir sorgunun araçsal olarak kullanılmasını gerektirir

Not: Her bir sorguyu kullanmak, bunları oluşturmanın otomatik bir yoluna sahip olmanız şart değildir.


Uygulama katmanı

Tabloda yasak olup olmadığını önceden kontrol edebilirsiniz null:

  • ana mantığı basitleştirir
  • arıza süresini iyileştirir
  • ön kontrol ve uygulama mantığının tutarlı olmasını gerektirir

Şunları yapabilirsiniz işlemi yarıda bir yasak karşılaştığında null:

  • hangi sütunların nullhangilerinin olabileceğini bilmiyor
  • hala nispeten basit (sadece bir çek + iade / atış)
  • işleminizin devam ettirilmesini gerektirir (zaten bir e-posta gönderdiyseniz, iki kez veya yüz kez göndermek istemezsiniz!)

Şunları yapabilirsiniz satır atlama bir yasak karşılaştığında null:

  • hangi sütunların nullhangilerinin olabileceğini bilmiyor
  • hala nispeten basit (sadece bir çek + iade / atış)
  • işleminizin devam etmesini gerektirmez

Şunları yapabilirsiniz Bir bildirim göndermek yasak bir karşılaştığında nullya bir seferde ya da başka yollar yukarıda sunulan ücretsiz olan toplu, tek. Bununla birlikte, en önemli olan "o zaman ne olur?", En önemlisi, satırın yamalanmasını ve yeniden işlenmeye ihtiyaç duymanız durumunda, önceden işlenmiş satırları ihtiyacı olan satırlardan ayırmanın bir yoluna sahip olduğunuzdan emin olmanız gerekebilir. yeniden işleniyor.


Durumunuz göz önüne alındığında, uygulamadaki durumu ele alıp aşağıdakilerden birini birleştiririm:

  • kes ve bildir
  • atla ve bildir

Özellikle işlem zaman alabilirse, bir şekilde bir miktar ilerlemeyi garanti etmek için mümkünse atlamaya eğilimliydim .

Atlanan satırları yeniden işlemeniz gerekmiyorsa, bunları günlüğe kaydetmenin yeterli olması gerekir ve işlem sonunda atlanan satır sayısı ile gönderilen bir e-posta uygun bir bildirim olacaktır.

Aksi takdirde, satırların düzeltilmesi (ve yeniden işlenmesi) için bir yan tablo kullanırdım. Bu yan tablo ya basit bir başvuru (yabancı anahtar olmadan) ya da tam bir kopya olabilir: ikincisi, daha pahalı olsa bile null, ana verileri temizlemek zorunda kalmadan önce adresleme zamanınız yoksa gereklidir .


-1

Null'ler, veritabanı türlerinin dil türlerine çevrilmesinde veya eşlenmesinde kullanılabilir. Örneğin C # 'da, işte size herhangi bir tür için null işleyen genel bir yöntem:

public static T Convert<T>(object obj)
        {
            if (obj == DBNull.Value)
            {
                return default(T);
            }

            return (T) obj;
        }

public static T Convert<T>(object obj, T defaultValue)
        {
            if (obj == DBNull.Value)
            {
                T t = defaultValue;
                return t;
            }

            return (T) obj;
        }

Veya eylem gerçekleştirmek istiyorsanız ...

 public static T Convert<T>(object obj, T defaultValue)
        {
            if (obj == DBNull.Value)
            {
                //Send an Alert, we might want pass in the name
                //of column or other details as well
                SendNullAlert();
                //Set it to default so we can keep processing
                T t = defaultValue;
                return t;
            }

            return (T) obj;
        }

Ve sonra eşlemede, bu durumda "Örnek" türünde bir nesneye, sütunlardan herhangi biri için null değerini işleyeceğiz:

public class SampleMapper : MapperBase<Sample>
    {
        private const string Id = "Id";
        private const string Name = "Name";
        private const string DataValue = "DataValue";
        private const string Created = "Created";

        protected override Sample Map(IDataRecord record)
        {
            return new Sample(
                Utility.Convert<Int64>(record[Id]),
                Utility.Convert<String>(record[Name]),
                Utility.Convert<Int32>(record[DataValue]),
                Utility.Convert<DateTime>(record[Created])
                );
        }
    }

Son olarak, tüm harita sınıfları SQL sorgularına veya SQL veri türlerine bakarak ve dile özgü veri türlerine çevrilerek tablolara göre otomatik olarak oluşturulabilir. Birçok ORM'nin sizin için otomatik olarak yaptığı budur. Bazı veritabanı türlerinin doğrudan bir eşlemesi olmayabilir (Coğrafi konumsal sütunlar vb.) Ve özel işlem gerektirebilir.


Birisi harika olurdu eşdeğer Java sürümünü göndermek istiyorsa ...
Jon Raynor

Örnek kodun Java geliştiricileri için de mükemmel anlaşılabilir olduğunu düşünüyorum. Benim durumumda zaten bir ORM var, bu yüzden bir tane uygulamak gerekmez. Ancak cevabınız yalnızca null değerleri için varsayılan değerleri ele alırken, benim durumumda aslında çok daha önemli olan bir null değeri algılamak ve bir eylemi tetiklemektir (örneğin, bir yöneticiyi hatalı veriler hakkında bilgilendirin).
jhyot

Ahhh, cevabımı buna dayanarak güncelleyeceğim.
Jon Raynor

Düzenlenmiş kodunuzda artık herhangi bir boş değer için bir varsayılan işlem vardır (yani tamamen geneldir). Bu, orijinal sorudaki 2. seçeneğime çok benziyor, yani sadece null atın ve bir yere yakalayın. Ancak burada belirtildiği gibi, eylemleri hangi değerin eksik olduğuna göre ayırmam gerekir.
jhyot
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.