Wow, die richtige Antwort "Lassen Sie keine NULL-Werte zu, wenn Sie das nicht müssen, weil sie die Leistung beeinträchtigen" ist irgendwie die zuletzt bewertete Antwort. Ich werde es unterstützen und ausarbeiten. Wenn ein RDBMS NULL für eine Spalte mit geringer Dichte zulässt, wird diese Spalte zu einer Bitmap hinzugefügt, in der nachverfolgt wird, ob der Wert für jede einzelne Zeile NULL ist. Wenn Sie also einer Spalte in einer Tabelle die NULL-Fähigkeit hinzufügen, in der alle Spalten keine NULL-Werte zulassen, erhöhen Sie den zum Speichern der Tabelle erforderlichen Speicherplatz. Außerdem muss das RDBMS die Bitmap lesen und darauf schreiben, was die Leistung bei allen Vorgängen beeinträchtigt.
In einigen Fällen kann das Zulassen von NULL 3NF unterbrechen. Stellen Sie sich das folgende Szenario vor, obwohl ich nicht wie viele meiner Kollegen ein Fan von 3NF bin:
In der Personentabelle gibt es eine Spalte mit dem Namen DateOfDeath, die auf Null gesetzt werden kann. Wenn eine Person gestorben ist, wird sie mit ihrem DateOfDeath ausgefüllt, andernfalls bleibt sie NULL. Es gibt auch eine nicht nullfähige Bitspalte mit dem Namen IsAlive. Diese Spalte wird auf 1 gesetzt, wenn die Person lebt, und auf 0, wenn die Person tot ist. Die überwiegende Mehrheit der gespeicherten Prozeduren verwendet die Spalte "IsAlive". Sie kümmern sich nur darum, ob eine Person am Leben ist, nicht um ihr DateOfDeath.
Die Spalte IsAlive unterbricht jedoch die Datenbanknormalisierung, da sie vollständig von DateOfDeath abgeleitet werden kann. Da IsAlive jedoch in den meisten SPs fest verdrahtet ist, besteht die einfache Lösung darin, DateOfDeath nicht auf Null zu setzen und der Spalte einen Standardwert zuzuweisen, falls die Person noch am Leben ist. Die wenigen SPs, die DateOfDeath verwenden, können dann umgeschrieben werden, um die IsAlive-Spalte zu überprüfen und das DateOfDeath nur dann zu berücksichtigen, wenn die Person nicht am Leben ist. Da sich die Mehrheit der SPs nur um IsAlive (ein bisschen) und nicht um DateOfDeath (ein Datum) kümmert, wird der Zugriff mit diesem Muster erheblich beschleunigt.
Ein nützliches T-SQL-Skript zum Auffinden nullbarer Spalten ohne NULL-Werte in allen Schemata ist:
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;
Wenn Sie dies auf einer Kopie Ihrer Produktionsdatenbank ausführen, finden Sie die Spaltenentwickler, die so markiert sind, dass sie NULL-Werte zulassen, die in der Praxis keine NULL-Werte haben. Die überwiegende Mehrheit von diesen kann als NOT NULL markiert werden, wodurch die Leistung erhöht und der Speicherplatz verringert wird.
Es ist möglicherweise nicht möglich, alle NULL-Werte in allen Tabellen zu entfernen, und das Design bleibt übersichtlich. Es ist jedoch von großem Vorteil, so viele NULL-Werte wie möglich zu entfernen. Der Optimierer arbeitet mit diesen Informationen viel schneller, und wenn Sie alle NULL-Werte in einer Tabelle entfernen können, können Sie beträchtlichen Speicherplatz zurückgewinnen.
Ich weiß, dass Datenbankadministratoren über Leistung nicht allzu viel nachdenken, aber Sie können nur eine begrenzte Menge an Arbeitsspeicher und Prozessorleistung in eine Lösung stecken, und irgendwann müssen Sie sich Gedanken über das logische und physische Design machen .
Beachten Sie auch, dass dies nur für echte RDBMS gilt und ich den technischen Teil meiner Antworten auf SQL Server beziehe. Das aufgelistete T-SQL zum Auffinden nullfähiger Spalten ohne Nullen stammt ebenfalls von SQL Server.