Ich habe eine Anwendung (Daten werden in PostgreSQL gespeichert), in der die meisten Felder in den Tabellen immer nicht null sind, aber das Schema für diese Tabellen erzwingt dies nicht. Schauen Sie sich zum Beispiel diese gefälschte Tabelle an:
CREATE TABLE "tbl" (
"id" serial,
"name" varchar(40),
"num" int,
"time" timestamp
PRIMARY KEY ("id"),
UNIQUE ("id")
);
Auch name
, num
, time
nicht explizit angegeben ist, wie NOT NULL
, in Wirklichkeit sind sie, weil die Durchsetzung auf der Anwendungsseite passiert.
Meiner Meinung nach sollte es geändert werden, aber der Kontrapunkt ist, dass die Anwendungsebene sicherstellt, dass hier keine Nullwerte angezeigt werden können und niemand anderes die Tabelle manuell ändert.
Meine Frage lautet : Was sind die Vorteile (Leistung, Speicher, Konsistenz, etwas anderes) und die Nachteile (vorausgesetzt, ich habe bereits überprüft, dass im Moment keine Nullen vorhanden sind, und aus der Geschäftslogik sollten keine Nullen vorhanden sein), indem Sie eine setzen explizite NOT NULL
Einschränkung?
Wir haben einen guten Codeüberprüfungsprozess und eine einigermaßen gute Dokumentation, sodass die Möglichkeit, dass eine neue Person etwas festlegt, das diese Einschränkung verletzt, nicht ausreicht, um die Änderung zu rechtfertigen.
Dies ist nicht meine Entscheidung, deshalb suche ich genau nach anderen Rechtfertigungen. Meiner Meinung nach, wenn etwas nicht null sein kann und Sie in einer Datenbank angeben können, dass etwas nicht null ist, dann tun Sie es einfach. Besonders wenn die Änderung super einfach ist.
quelle
NOT NULL
Einschränkungen haben keine direkte Auswirkung auf Speichergröße. Da alle Spalten definiert sindNOT NULL
, kann es natürlich zunächst keine Null-Bitmap geben. Auf der anderen Seite: Die Speichergröße ist normalerweise viel kleiner, wenn Sie NULL anstelle von "leeren" oder Dummy-Werten für Spalten ohne tatsächlichen Wert verwenden, da die Null-Bitmap vergleichsweise viel kleiner ist (mit Ausnahme seltener Kantenfälle).Antworten:
Was passiert, wenn ein neuer Programmierer eintrifft und eine App für diese Datenbank schreiben muss? Sie wissen nicht , dass Feld x hat zu sein
NOT NULL
.Ein anderes Programm könnte annehmen, dass alle Feld-Xs
NOT NULL
zum Durchführen von Zählungen bestimmt sind, aber einige sind jetztNULL
auf das neue Programm zurückzuführen, was zu inkonsistenten und schwer zu verfolgenden Fehlern führt.IMHO ist es immer am besten, Datenintegritätsregeln so nah wie möglich an den Daten, dh in der Datenbank, durchzusetzen. Auf diese Weise können neue Apps und / oder Programmierer Ihre Daten nicht durcheinander bringen.
Programmierer, Anwendungen, Sprachen und Frameworks kommen und gehen. Daten und Datenbanken bleiben in der Regel bestehen. Die Datenbank ist Ihre letzte Verteidigungslinie gegen inkonsistente, möglicherweise fehlerhafte Daten.
Machen maximale Nutzung Ihrer Datenbank Integrität Randbedingungserzwingung Mechanismen, auch auf Kosten der Leistung. Ein langsames System, das korrekte Ergebnisse liefert, ist einem schnellen System, das etwas falsch macht, unendlich überlegen!
quelle
IMHO it is always best to enforce data integrity rules as near to the data as possible
Das ist eigentlich das gleiche wie das Bauchgefühl, über das ich geschrieben habe. Und genau deshalb suche ich nach echten Rechtfertigungen. Wir haben eine Codeüberprüfung und eine gute Dokumentation, sodass Bedenken, dass ein neuer Entwickler etwas nicht weiß, nicht ausreichen, um die Änderung zu rechtfertigen.REAL PROGRAMMERS
lesen die gesamte (oder sogar eine) Dokumentation, bevor sie in ein Projekt geraten, in dem sie sich in einer engen Frist befinden?Wie bereits von anderen in Kommentaren zitiert, kann das Hinzufügen
NOT NULL
zu Ihrer Tabellenspezifikation die Leistung Ihrer Abfragen erheblich verbessern (zusätzlich zu den sehr guten methodischen Gründen, die in einer anderen Antwort angegeben sind).Der Grund dafür ist, dass der Abfrageoptimierer, der weiß, dass eine Spalte keinen
NULL
Wert haben kann, spezielle Tests für solche Werte ausschließen kann, wie im FallNOT IN
vs.NOT EXISTS
Sie können zum Beispiel dieses Blog sehen , in dem gezeigt wird, dass das Nichtdeklarieren eines FeldsNOT NULL
(wenn die Tabelle immer Nicht-Null-Werte enthält) mit einer bestimmten Abfrage die Ausführungszeit von 500% erhöht. Das Ergebnis wird für SQL Server angezeigt, aber ein ähnliches Verhalten kann in anderen relationalen DBMS wie Ihrem vorhanden sein (ganz zu schweigen von der Tatsache, dass Ihre Datenbank auf andere Systeme portiert werden könnte). Eine allgemeine Regel, die Sie annehmen können, lautet, dass effizientere Zugriffspläne erstellt werden können, wenn dem Abfrageoptimierer mehr Informationen zur Verfügung stehen.quelle
NOT NULL
aus mehreren Gründen definiert werden, kein Argument dafür. Der Link zum Blog über SQL Server gilt jedoch nicht für Postgres und beweist keine der von Ihnen erwähnten Auswirkungen auf die Leistung. Ich sage nicht, dass es keine gibt, aber ich würde gerne tatsächliche Beweise sehen .not in
für nullfähige Spalten ist jedoch unterschiedlich, sodass es einen Unterschied im Plan zwischen den beiden geben muss.Auswirkungen auf den Weltraum
Über die Auswirkungen auf den Weltraum wird in diesem Beitrag von @Erwin Brandstetter gesprochen
Kurz gesagt, Sie speichern ein
totalColumns - 8
Bit, das auf das nächste Byte (oderMAXALIGN
) aufgerundet ist , wenn Ihre Datenbank dies hatNOT NULL
Auswirkungen auf die Leistung
In diesem Beitrag über SE von @Erwin Brandstetter sagt er jedoch
@Renzo hat eine Antwort , die über die Auswirkungen auf die Leistung spricht - ich würde annehmen, dass nichts davon auf PostgreSQL anwendbar ist . Ich kann nichts , dass erhärtet finden alle davon als relevant zu PostgreSQL. Welche Zyklen auch immer gespeichert werden, kann selbst in der rudimentärsten Abfrage nicht quantifiziert werden.
Außerdem habe ich einige Tests durchgeführt, um festzustellen, ob NULL-Indizes immer schneller waren, und das konnte ich nicht belegen. Sie finden diesen äußerst nützlichen Thread von Scott Marlowe in den Mailinglisten, in dem es darum geht, dass der Abfrageplaner in 9.1 einen Teilindex für unterschiedliche WHERE-Klauseln verwenden kann. Ich habe dies getestet, indem ich Folgendes ausgeführt habe
Jetzt habe ich die Indizes erstellt,
In beiden Fällen konnte der Planer den Index bei der Auswahl verwenden
= 10
und bei der Suche nach NULL bzw. 0 einen seq-Scan verwenden. Beide Teilindizes waren gleich groß. Die vollständigen Indizes (nicht gezeigt) hatten dieselbe Größe. Nach der gleichen Methode habe ich die Tabelle mit einer Folge von1..1e5
und dem einen Null / 0-Wert und einer anderen Folge von geladen1..1e5
. Beide Methoden konnten die Null / 0 mit einem Index finden, der die gesamte Tabelle abdeckt.TLDR; Zusammenfassung
Ich kann auf die eine oder andere Weise nichts über die meisten Leistungsprobleme begründen, von denen ich dachte, dass sie es wert sind, getestet zu werden, um Unzulänglichkeiten des Planers einzubeziehen. Der Vorteil der Verwendung von null zum Speichern von RAM ist real. Der Speicherplatz, der durch die Nichtverwendung von null eingespart wird, ist vernachlässigbar. Dies ist eine Übertreibung bei Tabellen mit einer
NULLABLE
Spalte oder weniger als 8 Spalten. In diesen Fällen wird kein Speicherplatz gespeichert.quelle