Wow, la risposta corretta "Non consentire NULL quando non è necessario perché degradano le prestazioni" è in qualche modo l'ultima risposta valutata. Lo voterò ed elaborerò. Quando un RDBMS consente NULL per una colonna non sparsa, quella colonna viene aggiunta a una bitmap che tiene traccia del valore NULL per ogni singola riga. Quindi aggiungendo l'abilità NULL a una colonna in una tabella in cui tutte le colonne non consentono NULL, si aumenta lo spazio di archiviazione richiesto per salvare la tabella. Inoltre, è necessario che RDBMS legga e scriva sulla bitmap, compromettendo le prestazioni su tutte le operazioni.
Inoltre, in diversi casi, consentire NULL interromperà 3NF. Mentre non sono un pignolo per 3NF come molti dei miei colleghi, considera il seguente scenario:
Nella tabella Person c'è una colonna, chiamata DateOfDeath, che è nullable. Se una persona è morta, verrà compilata con la relativa DateOfDeath, altrimenti verrà lasciata NULL. Esiste anche una colonna di bit non annullabile denominata IsAlive. Questa colonna è impostata su 1 se la persona è viva e su 0 se la persona è morta. La stragrande maggioranza delle procedure memorizzate utilizza la colonna IsAlive, a loro importa solo se una persona è viva, non il loro DateOfDeath.
Tuttavia, la colonna IsAlive interrompe la normalizzazione del database, poiché è completamente derivabile da DateOfDeath. Ma poiché IsAlive è cablato nella maggior parte degli SP, la soluzione semplice è rendere DateOfDeath non nullable e assegnare un valore predefinito alla colonna nel caso in cui la persona sia ancora viva. I pochi SP che utilizzano DateOfDeath possono quindi essere riscritti per controllare la colonna IsAlive e onorare DateOfDeath solo se la persona non è viva. Ancora una volta, poiché la maggior parte degli SP si preoccupa solo di IsAlive (un po ') e non di DateOfDeath (una data) che utilizza questo schema accelera notevolmente l'accesso.
Un utile script T-SQL per trovare colonne nullable senza NULL in tutti gli schemi è:
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;
Se lo esegui su una copia del database di produzione, puoi trovare gli sviluppatori di colonne contrassegnati come che consentono NULL che non hanno NULL in pratica. La stragrande maggioranza di questi può essere contrassegnata come NOT NULL, aumentando così le prestazioni e riducendo lo spazio di archiviazione.
Potrebbe non essere possibile eliminare tutti i NULL in tutte le tabelle e avere comunque un design pulito, ma esiste un notevole vantaggio nell'eliminare il maggior numero possibile di NULL. L'ottimizzatore funziona molto più velocemente con queste informazioni e se puoi eliminare tutti i NULL in una tabella puoi recuperare una notevole quantità di spazio di archiviazione.
So che le prestazioni non sono qualcosa a cui i DBA pensano così tanto, ma puoi solo lanciare una quantità limitata di memoria e potenza del processore in una soluzione, un punto che dovrai iniziare a pensare al design logico e fisico .
Nota anche che questo è solo per RDBMS reali e sto basando la parte tecnica delle mie risposte su SQL Server. Anche il T-SQL elencato per trovare colonne nullable senza null proviene da SQL Server.