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.