Als CS-Student habe ich im Laufe der Jahre eine anständige Anzahl von Programmiersprachen gelernt, von denen die meisten das Konzept eines "nullbaren" oder "optionalen" Typs hatten. Beachten Sie, dass ich nicht über Nullzeiger oder Referenzen oder schwach typisierte Sprachen wie JavaScript spreche, in denen alles möglich ist null
. Beispiele für das, worüber ich spreche, sind boost::optional
(C ++), java.util.Optional
(Java 8.0), prelude.Maybe
(Haskell) und alle '?' Typen (zB int?
, float?
, C # und Kotlin). Dies sind Konstrukte, die einem zuvor nicht nullbaren Typ innerhalb eines strengen statischen Typsystems die Nullfähigkeit hinzufügen.
SQL hat ein ähnliches Konzept: Ein Typ INTEGER
, der nullbar oder nicht nullbar gemacht werden kann - aber es gibt eine Wendung. In SQL INTEGER
ist standardmäßig nullwertfähig und muss explizit so geschrieben INTEGER NOT NULL
werden, dass es nicht nullwertfähig ist.
Es erscheint mir äußerst kontraintuitiv und potenziell gefährlich, wenn NULL als Standardverhalten zugelassen wird. Offensichtlich gibt es SQL zu diesem Zeitpunkt schon so lange, dass (die meisten) SQL-Entwickler ein gesundes Bewusstsein für die Fallstricke von NULL entwickelt haben. Aber ich kann mir nur vorstellen, dass sich NULL in den frühen Tagen oft an unerwarteten und problematischen Orten eingeschlichen hat.
SQL ist älter als alle Beispiele, die ich bereitgestellt habe, daher ist es möglich, dass dies nur eine Frage der historischen Entwicklung ist. Trotzdem muss ich fragen, ob es einen guten Grund gibt, die Sprache so zu gestalten, dass Typen standardmäßig auf Null gesetzt werden können.
Wenn ja, ist dies nur ein historischer Grund oder hält die Logik dem heutigen Datenbankdesign stand?
Bearbeiten: Ich frage nicht, warum NULL ein Teil von SQL ist oder warum nullbare Spalten nützlich sind. Ich frage nur, warum Spalten standardmäßig nullbar sind . Warum schreiben wir zum Beispiel:
column1 FLOAT,
column2 FLOAT NOT NULL
Eher, als:
column1 FLOAT NULLABLE,
column2 FLOAT
quelle
Antworten:
An der Uni wurde mir beigebracht, dass das Gegenteil der Fall ist. Es ist viel gefährlicher, etwas
not null
ohne Grund zu machen . Bei einem nullbaren Feld ist das Schlimmste, was passieren kann, dass Sie über die Anwendung stolpern, die auf die Daten zugreift. Oh je, geh zurück und repariere die App ...Mit einem Nicht-Null-Feld können Sie keine Datensätze hinzufügen, da kein beliebiges Feld verfügbar ist. Jetzt müssen Sie das Datenmodell ändern und möglicherweise das Ergebnis an vielen verschiedenen Stellen korrigieren ...
Es ist gut, sich
null
"unbekannt" vorzustellen. Wenn es einen plausiblen Grund gibt, warum Sie einen Datensatz eingeben möchten, ohne etwas zu wissen, sollte er nullwertfähig sein.Einer meiner Universitätsdozenten hat es so beschrieben:
In der Praxis Reserve
not null
für Felder, die erforderlich sind, um die Aufzeichnung zu verstehen. Zum Beispiel:Eine Tabelle mit Orten mit Feldern (ID, Ortsname, Land, Längengrad, Breitengrad) ... "Längengrad" "Breitengrad" sollte nullwertfähig sein, damit Sie die Existenz eines Ortes speichern können, bevor Sie wissen, wo er sich befindet.
Wenn Sie jedoch eine Tabelle haben, deren einziger Zweck darin besteht, geografische Coodinaten mit Feldern (Item_id, Längengrad, Breitengrad) zu speichern, ist der gesamte Datensatz bedeutungslos, wenn Längen- und Breitengrad Null sind. Daher sollten sie in diesem Fall nicht null sein
Nach meiner Berufserfahrung seit der Uni gibt es weit mehr Bereiche, die optional sein können, als obligatorisch sein müssen.
quelle
Intuitiv ist im Auge des Betrachters und Ihre Meinung dazu wird durch die Dinge geprägt, denen Sie ausgesetzt waren. Ich komme aus einer Zeit, in der diese Art von Sicherheit nicht Standard war und die Werkzeuge nicht darauf hinwiesen, wann Sie vermasselt haben. Ich habe die Kettensäge lange genug ohne Klingenschutz verwendet, sodass mein erster Instinkt darin besteht, die Intuition vollständig zu vermeiden, zur DDL zurückzukehren und genau herauszufinden, welche Annahmen das Schema über die Daten machen wird.
Ich denke, Sie übertreiben die relativen Gefahren.
NOT NULL
hat seine eigenen Fallstricke, die zu ebenso heimtückischen Fehlern führen können. (Ihre Aufzählung wäre das Futter für eine andere Frage.)Der Designer einer Tabelle hat immer die Möglichkeit, eine Spalte
NULL
einzuschränken,NOT NULL
und wird das eine oder andere tun, um die Standardeinstellung zu umgehen, unabhängig davon, um was es sich handelt. Wenn eine Spalte nicht korrekt eingeschränkt wird, befolgt ein Entwickler die Geschäftsregeln nicht. Wenn Entwickler aufgrund der Definition der Spalte an anderer Stelle nicht das Richtige tun, kann er die Daten, die ihm übergeben werden, nicht verstehen. Es gibt auch keine technische Lösung.Nein, gibt es nicht. Da beide Gefahren bergen, gibt es auch keinen guten Grund, die Sprache anders zu gestalten. Es läuft darauf hinaus, Ihr Gift zu pflücken.
quelle
In SQL sind nullbare Spalten aufgrund äußerer Verknüpfungen erforderlich (auch als linke Verknüpfungen oder rechte Verknüpfungen bezeichnet). Wenn die Zeile auf einer Seite des Joins auf der anderen Seite nicht übereinstimmt, müssen die Felder für die andere Seite NULL-Werte enthalten. Da die Ausgabe eines Joins nullfähige Spalten haben kann, sollten Basistabellen diese aufgrund des Prinzips des relationalen Abschlusses ebenfalls unterstützen (die im Grunde angeben, dass das Ergebnis einer Abfrage oder Ansicht nicht von einer Basistabelle zu unterscheiden ist).
Vor diesem Hintergrund muss SQL nullfähige Spalten unterstützen. Auf der anderen Seite sind nicht nullfähige Spalten eine sekundäre Funktion - SQL könnte auch ohne sie funktionieren.
quelle
Lassen Sie es uns umdrehen und sagen, dass Sie Recht haben. Angenommen, Ihre Ganzzahl ist standardmäßig nicht null.
Das heißt, es muss standardmäßig einen Wert haben. Auch wenn es nicht bekannt ist.
Wenn Sie also Ihre Personentabelle aktualisieren und entweder zwei Möglichkeiten haben: Es ist unmöglich, die Tabelle zu aktualisieren, da Sie kein Gewicht eingegeben haben. Oder wenn Sie das Gewichtsargument nicht angegeben haben, wird es in den Standard "-1 Kilo" eingegeben, wenn es unbekannt ist.
Beide Situationen sind unerwünscht. Sie möchten Kunden hinzufügen können, auch wenn Sie deren Gewicht nicht kennen. Sie möchten aber auch keine "Proxy" -Werte haben. Werte, die Platzhalter sind, aber eine echte Bedeutung haben können, zum Beispiel: können in mathematischen Funktionen wie "Durchschnitt" verwendet werden, sind aber keine echten Werte.
Ich meine, bei der Berechnung eines Durchschnittsgewichts ist -1 ein gültiger Wert in Ihrer mathematischen Durchschnittsfunktion, aber nicht als Personengewicht. Sie verwenden null und jetzt weiß Ihre durchschnittliche Funktion, diesen Wert zu ignorieren.
Außerdem würde ich SQL nicht wirklich mit Programmiersprachen vergleichen, wenn ich über Nullen diskutiere. Sie sind von Natur aus unterschiedlich. Null in SQL ist ein wesentlicher Bestandteil der Theorie des relationalen Datenbankdesigns.
quelle
Nein. Es gibt keinen zwingenden Grund, warum SQL standardmäßig nullable ist. Tatsächlich haben viele prominente Forscher in der relationalen Datenbanktheorie dieser Entwurfsentscheidung widersprochen, vielleicht vor allem Chris Date , ein häufiger Mitarbeiter des ursprünglichen Designers der relationalen Datenbank, Edgar Codd . Date (zusammen mit Co-Autor Hugh Darwen) veröffentlichte ein bekanntes Buch über relationale Theorie (" The Third Manifesto "), das Prinzipien für alternative Designs für eine Familie relationaler Sprachen beschreibt, die sie "D" nennen, sowie ein Beispiel für eine solche Sprache namens "D". Tutorial D ".
D-Sprachen dürfen NULL-Werte nicht ausdrücklich unterstützen ("D darf kein Konzept einer" Beziehung "enthalten, in der ein" Tupel "ein" Attribut "enthält, das keinen Wert hat."). Stattdessen werden optionale Werte durch alternative Datentypen unterstützt, die Ortsmarker "nicht vorhanden" oder ähnliche Werte enthalten. D-Sprachen bieten ein umfangreiches Modell für benutzerdefinierte Typen, mit dem jeder native Typ um solche zusätzlichen Werte erweitert werden kann.
Es gibt überzeugende theoretische Gründe, warum dies eine gute Idee ist, und Date & Darwen haben viel darüber und über die anderen Entscheidungen, die sie in ihrem Design getroffen haben, geschrieben. Ich empfehle dringend, ihre Arbeit zu diesem Thema zu lesen.
quelle
Representing x with null is a bad idea
Schliesst nicht daraufallowing x by default is bad
. Ergo bedeutet das nicht, dassallowing null by default is bad where null is the only available representation of x
Not Present = Not Present
wo in SQL weder nochnull = null
odernull != null
wahr sind.Ich bin nicht anderer Meinung als Ihre Prämisse, wie die Standardeinstellung lauten soll, aber es ist eine gute Praxis, als Entwickler nichts anzunehmen. Das Überprüfen der Spezifikationen in einer Datenbanktabelle sollte nicht allzu schwierig sein.
Aus DBA-Sicht, bei der Sie insbesondere beim Zusammenführen von anderen Systemen aufgefordert werden, Daten in großen Mengen zu laden, sollten Sie die Einstellungen für jedes Feld besser kennen, unabhängig davon, ob Sie Daten in das Feld einfügen müssen oder nicht.
Unternehmen und Anwendungen werden von Menschen betrieben. Wenn sie kein Programmierer sind, sind die Definitionen von "nie" und "immer" nicht genau gleich und ändern sich im Laufe der Zeit. Die aktuelle Null-Einstellung für ein bestimmtes Feld sollte nicht unscharf sein.
quelle
Datenbanken unterscheiden sich von normalen Programmiersprachen.
Da das Schema einer Tabelle festgelegt ist, müssen beim Speichern der Informationen in einer Zeile alle Daten vorhanden sein. Viele dieser Daten sind jedoch möglicherweise nicht erforderlich, um eine gültige Darstellung eines Modellobjekts zu erstellen, sobald es in Ihren Code geladen wurde. Das Erfordernis, dass alle Daten nicht null sein und ausgefüllt werden müssen, bedeutet, dass diese nicht erforderlichen Felder einen Wert enthalten müssen und noch keinen haben. Sie sind "unbekannt".
Stellen Sie sich vor, Sie müssen die ganze Zeit ALLE Felder in Webformularen ausfüllen, da sie in der Datenbank nicht null sein dürfen. Sie müssen einen Wert erhalten ... ein Rezept für Wahnsinn!
Sie können einige reservierte Werte festlegen, um das Fehlen von Daten, eine leere Zeichenfolge, eine bestimmte Nummer, ein bestimmtes Datum usw. abhängig vom Datentyp darzustellen. Welchen Wert wählen Sie jedoch aus? Dann müssen Sie sicherstellen, dass alle zustimmen, dass diese willkürlichen Werte tatsächlich "unbekannt" und nicht beispielsweise "1. Januar 1970" bedeuten. Null-Abneigung kann viele Formen annehmen und Sie auf lange, verschlungene Umwege führen, nur weil jemand sagte, Nullen seien schlecht. Wie komplex sind Sie bereit, nur um den Umgang mit Nullen zu vermeiden?
Ich habe einen einzigen universellen Wert für alles Unbekannte und finde es viel besser, einen Satz beliebiger konstanter Werte zu verwenden. Ich sage nicht, dass konstante Werte schlecht und null besser sind. Wenn Ihr Modell durch eine Konstante zur Darstellung dieser Informationen gut bedient wird, verwenden Sie diese auf jeden Fall, aber es gibt viele Situationen, in denen eine Null genau das ist, was am besten passt. Für alle Nullhasser ist dies eine Situation, in der Null erfunden werden müsste, wenn Null verweigert würde!
Wenn man sieht, wie weit verbreitet das Konzept "unbekannt" in einer Datenbank ist, dann würde ich sagen, dass es sehr sinnvoll ist, die Werte auf Null zu setzen.
Wenn ich hier tiefer gehe und andere Antworten betrachte, wäre ich nicht überrascht zu erfahren, dass Nullen nicht nur ein "Sprachmerkmal" sind, sondern ein wesentlicher Bestandteil der zugrunde liegenden Theorie, auf der SQL basiert. Man kann C (die Lichtgeschwindigkeit) aus der Relativitätstheorie entfernen, aber das Konzept der absoluten Höchstgeschwindigkeit bleibt bestehen und muss immer noch ausgedrückt werden, damit es in irgendeiner Form zurückkehrt.
quelle
Kurze Antwort: Abwärtskompatibilität.
Lange Antwort:
In einer vollständig normalisierten Datenbank ist NULL in keiner Spalte zulässig. Angenommen, es gibt eine Tabelle namens MailingAddress mit einer Spalte PostOfficeBox, die eine Ganzzahl ist. Da nicht jeder ein Postfach hat, gibt es zwei Möglichkeiten, dies umzusetzen.
Erstens könnte NULL in der Spalte erlaubt sein.
Zweitens wird PostOfficeBox aus MailingAddress entfernt und eine neue Tabelle erstellt. PostOfficeBox wird mit einer Spaltennummer erstellt, deren PK die FK für MailingAddress ist. Jetzt sind zwei Abfragen erforderlich, um Postanschriften zu erhalten: eine für diejenigen ohne Postfach und eine für diejenigen mit.
SQL erlaubt aus praktischen Gründen NULL-Werte in Spalten.
quelle