NULL’lara neden izin vermiyoruz?


125

Veri tabanı tasarımı ile ilgili bu makaleyi okuduğumu hatırlıyorum ve ayrıca NOT NULL alan özelliklerine sahip olmanız gerektiğini söylediğini de hatırlıyorum. Neden böyle olduğunu hatırlamıyorum.

Aklıma gelen tek şey, bir uygulama geliştiricisi olarak NULL ve var olmayan bir veri değerini (örneğin, dizeler için boş bir dize) test etmek zorunda kalmayacağınızdır .

Ancak tarih, tarih ve saat durumunda ne yaparsınız (SQL Server 2008)? Bazı tarihi veya dip tarihi kullanırsınız.

Bu konuda fikrin var mı?



10
Gerçekten mi? Neden kullanmamamız gerekiyorsa, RDBMS neden NULL kullanmamızı sağlıyor? Onlarla nasıl başa çıkılacağını bildiğiniz sürece NULL'da yanlış bir şey yoktur.
Fr0zenFyr

3
Bu bir BI veri modellemesi miydi? Genel olarak boş tablolara aslında izin vermemelisiniz ... aksi halde, doğru kullanıldığında boş arkadaşsınız demektir. =)
sam yi

2
@ Fr0zenFyr, sadece bir RDBMS bir şey yapmamıza izin verdiği için bunu yapmak için mutlaka iyi bir fikir değildir. Hiçbir şey bizi bir birincil anahtar veya bir tablodaki benzersiz bir anahtar ilan etmeye zorlamaz, ancak bazı istisnalar dışında zaten yaparız.
Lennart

3
Bu konunun eksiksiz bir şekilde ele alınmasının, Codd'nin bir RDBMS'nin eksik verileri tedavi etmenin sistematik bir yoluna sahip olması gerektiği yönündeki orijinal şartına atıfta bulunması gerektiğini düşünüyorum. Gerçek dünyada, veriler için bir konumun yaratıldığı durumlar vardır, ancak içine konacak veri yoktur. Veri Mimarı, veri tabanı tasarımı, uygulama programlaması veya her ikisini de içeriyor olsun, buna bir cevap vermelidir. SQL NULL bu gereksinimi karşılamada mükemmel olmaktan az, ancak hiç yoktan iyidir.
Walter Mitty

Yanıtlar:


230

Bence bu soru tam olarak ifade edilmedi, zira ifadeler NULL’ların kötü olduğuna karar verdiğinizi ima ediyor. Belki de "NULL’lara izin verelim mi?" Demek istedin.

Her neyse, işte benim üstümde: NULL'lerin iyi bir şey olduğunu düşünüyorum. NULL'ları önlemeye başladığınızda, yalnızca "NULL'lar kötü" veya "NULL'lar zor" olur, veri oluşturmaya başlarsınız. Örneğin, doğum tarihimi bilmiyorsanız ne olacak? Bilene kadar sütuna ne yazacaksın? Çok sayıda NULL karşıtı insan gibi bir şey iseniz, 1900-01-01'e gireceksiniz. Şimdi geriatrik koğuşuna yerleştirileceğim ve muhtemelen yerel haber istasyonumdan beni uzun ömürlü olduğum için tebrik eden, bu kadar uzun bir yaşam sürdürmenin sırlarını soranları vb. Arayacağım.

Bir satır Eğer bu mümkün olduğu girilebilir Eğer bilmiyorsanız bir sütunun değerini, ben BOŞ bilinmeyen olduğu gerçeğini temsil etmek bazı keyfi belirteç değeri toplama çok daha fazla mantıklı düşünmek - hangi diğerleri olacak bir değer Zaten bilmesi, tersine mühendislik yapması veya ne anlama geldiğini öğrenmesi için sormanız gerekir.

Yine de bir denge var - veri modelinizdeki her sütun geçersiz olabilir. Bir formda genellikle isteğe bağlı alanlar veya satır oluşturulduğu sırada toplanmayan bilgi parçaları bulunur. Ancak bu, tüm verileri doldurmayı erteleyebileceğiniz anlamına gelmez . :-)

Ayrıca NULL kullanma yeteneği gerçek hayatta çok önemli gereksinimlerle sınırlandırılabilir. Örneğin tıp alanında, bir değerin neden bilinmediğini bilmek ölüm kalım meselesi olabilir . Nabız olmadığından veya henüz ölçemediğimiz için kalp atış hızı NULL mu? Böyle bir durumda kalp atış hızı sütununa NULL koyabilir ve NULL-sebep nedeni ile notları veya farklı bir sütunu alabilir miyiz?

NULL'lardan korkmayın, ne zaman ve nerede kullanılması gerektiğini ve ne zaman ve nerede kullanmaları gerektiğini öğrenmek veya dikte etmeye istekli olun.


3
"bilinmeyen gerçeği temsil eden bazı keyfi belirteçler" bu bir sentinel değeri
Alexander

4
Ancak birth_datedoğum tarihlerini sakladığınız ayrı bir tablo oluşturmanızı önleyen nedir? Doğum tarihi bilinmiyorsa, doğum tarihini eklemeyin birth_date. Boşlar felakettir.
Eldar Agalarov

6
@EldarAgalarov Trump muhakeme gibi geliyor (“felaket” neden? Nasıl? Kim için? Bir şeyin bir “felaket” olduğu görüşünüz bunu yapmaz). Neyse doğum tarihi sadece bir örnektir. Potansiyel olarak açılabilir 15 sütunu olan personeliniz veya üyeleriniz veya müşterileriniz varsa, 15 ikincil tablo oluşturacak mısınız? Ya 50 yaşın varsa? DW bilgi çizelgenizde 500 varsa? Büyük kötü korkutucu tutulması için bakım NULL'lar veritabanınızdan uzak, korktuğunuz herhangi bir "felaket" kadar 10 kat daha kötü hale gelir ...
Aaron Bertrand

3
@AaronBertrand, tablonuzda potansiyel olarak nulla olabilecek 15 sütun varsa, gerçekten kötü kokuyor ^^ Ancak soruları gündeme getirecektir.
programat,

2
@Wildcard Yani 1900-01-01NULL tarih / saat değerine sahip olmaktan kaçınan insanları hiç görmediniz mi? Tamam ozaman. Ayrıca, NULL = bilinmiyor ve bilinmiyor = yanlış. Bunun, insanların bilmeden doğmalarının neden olamayacağından emin değilim (karmaşık bir RDBMS'de bulunan birçok şeyi bilerek doğmadıkları gibi). Yine, el sallayarak ve "Sorun! Afet!" o kadar yapmaz.
Aaron Bertrand

57

Yerleşik sebepler:

  • NULL bir değer değildir ve bu nedenle kendine özgü bir veri türü yoktur. Null'ların her yerde özel işlem yapmaları gerekir ; aksi takdirde gerçek türlere dayanan kod da yazılmamış NULL'u alabilir.

  • NULL, iki değerli (tanıdık Doğru veya Yanlış) mantığını keser ve üç değerli bir mantık gerektirir. Bu, doğru bir şekilde uygulamak için bile çok daha karmaşıktır ve çoğu DBA ve hemen hemen tüm DBA olmayanlar tarafından açıkça anlaşılmamaktadır. Sonuç olarak, uygulamada birçok ince hatayı olumlu bir şekilde davet etmektedir.

  • Belirli bir NULL anlamsal olarak uygulama bırakılır gerçek değerler farklı olarak,.

    “Uygulanamaz” ve “bilinmeyen” ve “sentinel” gibi anlambilim yaygındır ve başkaları da vardır. Aynı ilişki içinde bile, aynı veritabanı içerisinde sık sık aynı anda kullanılırlar; ve elbette, anlaşılmaz ve ayırt edilemez ve uyumsuz anlamlar.

  • Onlar ilişkisel veri tabanlarına gerekli değildir da iddia edildiği gibi, “Nulls olmadan bilgiler eksik tanıtıcı nasıl” . Daha fazla normalleştirme, NULL'lardan oluşan bir tabloyu denemeyi denemek için açık bir ilk adımdır.

Bu, NULL'a asla izin verilmemesi gerektiği anlamına gelmez. Bu vermez yerde uygulanabilir NULL izin vermemek için birçok iyi nedeni vardır savunuyorlar.

Daha da önemlisi, NULL’dan daha sık kaçınılması mümkün kılmak için daha iyi şema tasarımı ve daha iyi veritabanı motorları ve daha iyi veritabanı dilleri yoluyla çok sıkı çalışmayı savunuyor .

Fabian Pascal, “Nulls Nullified” içindeki bir dizi tartışmaya cevap verir .


3
"Null'lar olmadan Eksik Bilgilerin Nasıl Kullanılacağı" bağlantınız null'lar olmadan niçin niçin yapamayacağımızı gayet iyi gösteriyor: Önerilerin birçoğunun hali hazırda olduğu gibi büyük RDBMS'lere rasyonel bir şekilde uygulanması imkansız olacak.
Jack Douglas

7
Jack
Archer

17
Bu uçaklar mükemmel olmadığı için uçmamamız gerektiğini söylemek gibi bir şey mi?
Aaron Bertrand

11
Hayır, üreticilerin kırk yıl önce geçerli olabilecek nulllar için mazeret çağrıları durdurması gerektiğini, ancak makul alıkoyma sürelerinin çok daha uzun sürdüğünü söylüyor. G / Ç zamanları artık 80ms büyüklüğünde değildir. Tek CPU döngüleri artık mikrosaniye büyüklüğünde değildir. Hafıza limitleri artık birkaç Megs büyüklüğünde değildir. Kırk yıl önce aksine, boşta çalışmak için gereken donanım hızları ve kapasiteleri şimdi DO'yu yasaklamamaktadır. Devam etme zamanının geldiğini söylüyor.
Erwin Smout,

2
"NULL karışıklık" bağlantısı öldü.
jpmc26

32

Kabul etmiyorum, boşlar veritabanı tasarımının önemli bir unsurudur. Alternatif, sizin de ima ettiğiniz gibi, eksik veya bilinmeyeni temsil etmek için bilinen değerlerin çoğalması olacaktır. Sorun, çok fazla yanlış anlaşılmaması ve bunun sonucunda uygun olmayan şekilde kullanılması null ile yatıyor.

IIRC, Codd, null uygulamasının (mevcut / eksik anlamına gelmeyen), "mevcut değil ancak uygulanabilir" ve "mevcut değil ve uygulanamaz" yerine iki null işaretleyiciye sahip olarak iyileştirilebileceğini öne sürdü. İlişkisel tasarımların bu şekilde nasıl kişisel olarak geliştirileceğini öngöremiyorum.


2
Kullanıcı tanımlı bir dizi farklı türde nullve kullanıcı tanımlı bir çok değerli mantığa sahip olmayı öneriyorum : p
Jack Douglas

13
Bunlar tek seçenek değil. Normalleştirme alternatifini hariç tutuyorsunuz: Değeri olan veya olmayan sütunlar yerine, ilk tablo için karşılık gelen bir satırı olan veya bulunmayan başka bir tablo kullanın. Varlığında ya da arka arkaya yokluğunda anlamı tablo anlamı gerektirdiği edilir ve NULL veya şahit değerleri vb özel bir kılıfı vardır
bignose

7
NULL varlığı özel muhafaza veya sentinel değerleri gerektirmez. Bunlar sadece bazı kişilerin NULL’lerle uğraşmaya karar vermelerinin bir belirtisi.
Aaron Bertrand

'' PostgreSQL'de (Oracle olmasa da) null değerinden farklı olduğunu ve bu nedenle size iki katlı bir işaretleyici sunduğunu ve sayısal sütunlar için 0 kullanabileceğinizi belirtmek önemlidir. 0'daki sorun ise yabancı anahtarlar için işe yaramamasıdır.
Chris,

13

Bir DBA olmadığımı söyleyerek başlayalım, kalpten bir geliştiriciyim ve ihtiyaçlarımızı temel alarak veritabanlarımızı korudum ve güncelliyorum. Olduğu söyleniyor, birkaç nedenden dolayı aynı soruyu vardı.

  1. Boş değerler gelişimi daha zor ve hataya açık hale getirir.
  2. Boş değerler, sorgulamalar, saklı yordamlar yapar ve görünümleri daha karmaşık ve hataya açık hale getirir.
  3. Boş değerler yer kaplar (sabit sütun uzunluğunu temel alan? Bayt veya değişken sütun uzunluğu için 2 bayt).
  4. Boş değerler endekslemeyi ve matematiği etkileyebilir ve sık sık etkiler.

Çok fazla zaman harcayarak yanıtları, yorumları, makaleleri ve tavsiyeleri internette bulabilirim. Söylemeye gerek yok, bilginin çoğu @ AaronBertrand'ın tepkisi ile aynıydı. Bu yüzden bu soruya cevap vermem gerektiğini hissettim.

Öncelikle gelecekteki tüm okuyucular için düz bir şeyler ayarlamak istiyorum ... NULL değerler, bilinmeyen verileri, kullanılmayan verileri temsil etmiyor. Sonlandırma tarihi olan bir çalışan masanız varsa. Fesih tarihindeki boş değer, şu anda bilinmeyen gelecekteki bir zorunlu alandır. Her çalışan aktif veya feshedilmiş ise bir noktada o alana eklenen bir tarih olacaktır. Bu bence Nullable alanının tek ve tek nedeni.

Aynı çalışan tablosunun büyük olasılıkla bir tür kimlik doğrulama verisine sahip olacağı söyleniyor. Bir işletme ortamında, çalışanların İK ve muhasebe için veritabanında listelenmesi yaygındır, ancak her zaman kimlik doğrulama ayrıntılarına sahip olmaları gerekmez. Yanıtların çoğu, bu alanları boşalttığınıza ya da bazı durumlarda onlar için bir hesap oluşturduğuna, ancak hiçbir zaman kimlik bilgilerini göndermediğine inanmanıza yol açacaktır. İlki, geliştirme ekibinizin NULL'ları kontrol etmek için kod yazmasına ve buna göre başa çıkmalarına neden olacak ve ikincisi büyük bir güvenlik riski doğuracaktır! Henüz sistemde hiç kullanılmamış olan hesaplar yalnızca bir bilgisayar korsanı için erişim noktalarının sayısını artırır, ayrıca hiç kullanılmayan bir şey için değerli veritabanı alanı kullanır.

Yukarıdaki bilgiler göz önüne alındığında, kullanılacak olan null verilerle başa çıkmanın en iyi yolu null değerlerine izin vermektir. Bu üzücü ama doğru ve geliştiricilerin bunun için senden nefret edecek. İkinci tür null veri, ilgili bir tabloya (IE: Hesap, Kimlik Bilgileri, vb.) Konulmalı ve Bire Bir ilişkiye sahip olmalıdır. Bu, bir kullanıcının gerekli olmadıkça kimlik bilgisi olmadan var olmasına izin verir. Bu, ekstra güvenlik riskini, değerli veritabanı alanını ortadan kaldırır ve daha temiz bir veritabanı sağlar.

Aşağıda hem gerekli null sütununu hem de bire-bir ilişkiyi gösteren çok basit bir tablo yapısı gösterilmektedir.

Bilinmeyen Null ve Bire Bir İlişki

Partiye biraz geç kaldığımı biliyorum, çünkü bu soru yıllar önce sorulmuştu, ancak umarım bu, bu konuya biraz ışık tutmaya ve bununla nasıl başa çıkılacağına yardımcı olacaktır.


2
Ben sadece hayır olacak şekilde değiştirmek istiyorsunuz TerminationDateçalışan kayıtlarında, ancak bir tablo var TerminatedEmployeeonlar tamamlandıkça çalışanların uygulama tarafından taşındı (kopyalanmaz) hangi. Açıkçası bu, Hesap tablosu ile iyi çalışır çünkü masada hesap yoktur TerminatedEmployee. Hala telefon numaralarına ihtiyacınız varsa, yabancı anahtarları tersine çeviririm, böylece çalışan ve sonlandırılan çalışan masaları, telefon numaralarının kimliğini başka bir yolla değil.
Programcı

2
Bunun neden kötü olacağı konusunda tam anlamıyla günlerce devam edebilirim. Gereksiz tablolar, kötü SQL uygulamaları, geliştiricilerin çalışan verilerini iki yerde aramaları, raporlama ile ilgili sorunları, var olmayan (taşınmış) bir çalışana doğrudan URI'yla ilgili sorunları incelemelerini sağlar. ve üzerinde. Bir gün değeri olacak alanlar için NULLS olması tamamen iyidir, asla doldurulmamış ve hiç kullanımı olmayan alanların olması başka bir hikaye. Bu çalışmayı yapmak için bazı olası sorunlar ve geçici çözümler, bir alanda NULL'u kontrol etmenin küçük bir konusuna değmez.
Nicholas Aguirre

1
Katılmıyorum. Gereksiz olan tek şey, sonlandırma tarihi için hiçbir zaman doldurulamayacak boş alandır. Geliştiriciler yalnızca istedikleri veriler için uygun tabloya bakmalı ve performansı artırabilir. Herhangi bir sebepten ötürü hem fesih hem fesih olmayan çalışanları istiyorsanız, bir katılımla çözülür, ancak başvurunuzun muhtemelen% 90'ı birinden diğerini isteyecektir. Ben belirttiğim düzenin daha iyi olduğunu düşünüyorum çünkü bir çalışanın üzerinde bir sonlandırma tarihi olması ve hala bir hesaba sahip olması imkansız olacak.
Programcı

2
Yedekli veri demedim, gereksiz tablolar söyledim. Ayrıca, çalışan masalarında yapılacak herhangi bir değişiklik sonlandırılmış masalara daraltılmalıdır; Bu, uygulamanın hataya açık olmasını sağlar ve geliştiricinin işini çok daha zorlaştırır. Ayrıca, bir Fesih tarihi alanı neredeyse herkes için doldurulacak. İkinci bir aynı tablo yapısı oluşturmak ve ayrıca verileri dolaşmak israf ve problemlidir. Tablo verilerinin taşındığından ve temizlendiğinden emin olmak için her seferinde testi dahil etmemek. Verileri bir tablodan kaldırmak, yalnızca taşımak bile olsa, kötü bir uygulamadır. Tek bir alanla çok ilgileniyorsanız ...
Nicholas Aguirre

1
... bu neredeyse her zaman zamanında doldurulacak ve daha sonra çalışanlarla 1'e 1 ilişki kuracak şekilde sonlandırılmış bir tablo hazırlayacak. Tüm gün boyunca hem DBA hem de geliştirici olarak çeşitli veritabanlarıyla çalışıyorum ve önerdiğiniz yapıyla henüz karşılaştığım için mutluyum. Özellikle geliştiricinin bakış açısından, hangi tablodan geldiğini bilmeyeceğiniz için her şeyi yazıp hatayla kontrol etmek kabus olurdu. Bir birleştirme bile yazılsa, yazılıma geri gönderilen verilerde yine de onu test etmenizi gerektiren boş veri içeren bir alan olacaktır.
Nicholas Aguirre

13

NULL'un kafa karıştırıcı geliştiricileri ile ilgili tüm sorunların yanı sıra, NULL'lerin çok ciddi bir dezavantajı var: Performans

Boş NULL'able sütunlar, performans açısından bir felakettir. Tamsayıların aritmetiğini örnek olarak düşünün. NULL olmayan akıllı bir dünyada, CPU döngüsü başına 1 satırdan daha hızlı hızlarda hemen hemen herhangi bir hesaplama yapmak için SIMD komutlarını kullanarak veritabanı motor kodunda tamsayı aritmetiğini vektörelemek "kolaydır". Ancak, NULL’u tanıttığınız an, NULL’un yarattığı tüm özel durumları ele almanız gerekir. Modern CPU komut setleri (okuma: x86 / x64 / ARM ve GPU mantığı da) bunu verimli bir şekilde yapmak için uygun değildir.

Bölünmeyi örnek olarak düşünün. Çok yüksek bir düzeyde, boş olmayan bir tamsayı ile ihtiyacınız olan mantık şudur:

if (b == 0)
  do something when dividing by error
else
  return a / b

NULL ile, bu biraz daha zor olur. Birlikte null ve benzer şekilde bise bir göstergeye ihtiyacınız olacak . Şimdi çek olur:ba

if (b_null_bit == NULL)
   return NULL
else if (b == 0) 
   do something when dividing by error
else if (a_null_bit == NULL)
   return NULL
else 
   return a / b

NULL aritmetiği, modern bir CPU üzerinde çalışması için boş olmayan aritmetikten önemli ölçüde yavaştır (2-3x civarında).

SIMD'yi tanıttığınızda daha da kötüleşiyor. SIMD ile, modern bir Intel CPU tek bir komutla 4 x 32-bit tam sayı bölme yapabilir:

x_vector = a_vector / b_vector
if (fetestexception(FE_DIVBYZERO))
   do something when dividing by zero
return x_vector;

Şimdi, NULL'u SIMD ülkesinde ele almanın da yolları var, ancak bu daha fazla vektör ve CPU kaydı kullanarak ve biraz akıllıca maskeleme gerektiriyor. İyi numaralarla bile, NULL tamsayı aritmetiğinin performans cezası, göreceli olarak basit ifadeler için bile 5-10x daha yavaş aralığa yayılır.

Yukarıdaki gibi bir şey toplamlar ve bir ölçüde de katılımlar için geçerlidir.

Başka bir deyişle: SQL'de NULL'un varlığı, veritabanı teorisi ile modern bilgisayarların gerçek tasarımı arasındaki bir empedans uyumsuzluğudur. NULL, geliştiricilerin kafasını karıştırmak için oldukça iyi bir neden var - çünkü çoğu mantıklı programlama dilinde bir tamsayı NULL olamaz - bu, bilgisayarların nasıl çalıştığını değil.


10

İlginç sorular

Aklıma gelen tek şey, bir uygulama geliştiricisi olarak NULL ve var olmayan bir veri değerini (örneğin, dizeler için boş bir dize) test etmek zorunda kalmayacağınızdır.

Bundan daha karmaşık. Boş değerin çok sayıda farklı anlamı vardır ve birçok sütunda boş satırlara izin vermemek için gerçekten önemli bir neden, sütun boş olduğunda bunun tek ve tek bir şey anlamına gelmesidir (dış birleşimde görünmediği). Ek olarak, gerçekten yararlı olan minimum veri girişi standartlarını belirlemenizi sağlar.

Ancak tarih, tarih ve saat durumunda ne yaparsınız (SQL Server 2008)? Bazı tarihi veya dip tarihi kullanırsınız.

Bu hemen boş olan bir sorunu gösterir, yani bir tabloda saklanan bir değer "bu değer uygulanmaz" veya "biz bilmiyoruz" anlamına gelebilir. Dizelerle boş bir dizge "bu geçerli değildir" olarak hizmet edebilir, ancak tarih ve saatlerle böyle bir kural yoktur, çünkü geleneksel olarak bunun anlamı olan geçerli bir değer yoktur. Normalde orada NULL kullanarak sıkışmış olacaksınız.

Bunu aşmanın yolları var (daha fazla ilişki ekleyerek ve katılarak) ancak bunlar veritabanında NULL'ların yaptığı gibi aynı anlamsal netlik problemlerini ortaya koyuyor. Bu veritabanları için bu konuda endişelenmem. Sadece bu konuda gerçekten yapabileceğin bir şey yok.

DÜZENLEME: Bir alan NULL olan vazgeçilmez yabancı anahtarlar bulunmaktadır. Burada genellikle dış birleştirme anlamındaki boş değerle aynı olan tek bir anlamı vardır. Bu elbette sorunun bir istisnasıdır.


10

Wikipedia'nın SQL Null hakkındaki makalesinde , NULL değeri hakkında bazı ilginç açıklamalar var ve belirli RDBMS'niz için NULL değerlerine sahip olmanın potansiyel etkilerinin farkında olduğunuz sürece, veritabanında-agnostik bir cevap olarak, tasarımınızda kabul edilebilirler. Olmazlarsa, sütunları null olarak tanımlayamazsınız.

RDBMS'nizin onları matematik gibi SELECT işlemlerinde ve ayrıca Dizinlerde nasıl kullandığının farkında olun.


-12

Vay canına, doğru cevap "Performansınızı düşürdüğü için NULL’lara izin verme." Bir şekilde en son verilen cevap. Ben onu affedeceğim ve detaylandırıyorum. Bir RDBMS, seyrek olmayan bir sütun için NULL'lara izin verdiğinde, bu sütun, her bir satır için değerin NULL olup olmadığını izleyen bir bitmap'e eklenir. Bu nedenle, tüm sütunların NULL'lara izin vermediği bir tablodaki bir sütuna NULL yeteneği ekleyerek, tabloyu kaydetmek için gereken depolama alanını arttırırsınız. Ayrıca, RDBMS'nin tüm işlemlerde performansı düşüren bitmap'i okuyup yazmasını istiyorsunuz.

Ayrıca, bazı durumlarda, NULL'lere izin vermek 3NF'yi kırar. Birçok meslektaşım gibi 3NF için bir yapıştırıcı olmasam da, aşağıdaki senaryoyu inceleyin:

Kişi tablosunda, tarihlenebilir olan ve DateOfDeath adlı bir sütun var. Bir kişi öldüğünde, DateOfDeath ile doldurulur, aksi takdirde NULL kalır. IsAlive adında null olmayan bir bit sütunu vardır. Bu sütun, kişi hayatta ise 1, kişi ölü ise 0 olarak ayarlanmıştır. Saklı yordamların büyük çoğunluğu IsAlive sütununu kullanır, yalnızca DateOfDeath'larını değil, bir kişinin hayatta olup olmadığını önemser.

Ancak, IsAlive sütunu, DateOfDeath öğesinden tamamen türetilebildiği için veritabanı normalleştirmesini bozar. Ancak IsAlive, SP'lerin çoğuna kabloyla bağlandığından, basit çözüm, DateOfDeath ürününü null yapamaz hale getirmek ve kişinin hala hayatta olduğu durumda sütuna varsayılan bir değer atamaktır. DateOfDeath kullanan birkaç SP, IsAlive sütununu kontrol etmek için yeniden yazılabilir ve kişi canlı değilse, yalnızca DateOfDeath'i onurlandırır. Yine, SP'lerin çoğunluğu yalnızca IsAlive'yi (biraz) önemser ve bu modeli kullanarak DateOfDeath (bir tarih) değil, erişimi önemli ölçüde hızlandırır.

Tüm şemalarda NULL içermeyen null sütunlarını bulmak için yararlı bir T-SQL komut dosyası:

select 'IF NOT EXISTS (SELECT 1 FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' WHERE ' + QUOTENAME(c.name) + ' IS NULL)
    AND (SELECT COUNT(*) FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ') > 1 PRINT ''' + s.name + '.' + t.name + '.' + REPLACE(c.name, '''', '''''') + ''''
    from sys.columns c
    inner join sys.tables t ON c.object_id = t.object_id
    inner join sys.schemas s ON s.schema_id = t.schema_id
    where c.is_nullable = 1 AND c.is_computed = 0
    order by s.name, t.name, c.name;

Bunu üretim veritabanınızın bir kopyasında çalıştırırsanız, pratikte NULL içermeyen NULL'lara izin veren olarak işaretlenmiş sütun geliştiricilerini bulabilirsiniz. Bunların büyük çoğunluğu NOT NULL olarak işaretlenebilir, böylece performans artar ve depolama alanı azalır.

Tüm tablolardaki tüm NULL'ların ortadan kaldırılması mümkün olmayabilir ve yine de temiz bir tasarıma sahip olabilir, ancak mümkün olduğu kadar NULL'lerin elimine edilmesinde önemli bir avantaj vardır. En iyi duruma getirici bu bilgilerle çok daha hızlı çalışır ve bir tablodaki tüm NULL'ları ortadan kaldırabilirseniz önemli miktarda depolama alanı kazanabilirsiniz.

Performansın DBA'ların hepsi hakkında çok fazla düşündükleri bir şey olmadığını biliyorum, ancak mantıklı ve fiziksel tasarım hakkında düşünmeye başlamanız gereken bir noktaya bir çözüme yalnızca sınırlı miktarda bellek ve işlemci gücü atabilirsiniz. .

Ayrıca bunun yalnızca gerçek RDBMS'ler için olduğunu ve yanıtlarımın teknik bölümünü SQL Server üzerinden aldığımı unutmayın. Boş değer içermeyen null sütunlarını bulmak için listelenen T-SQL de SQL Server'dandır.


1
Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Paul Beyaz
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.