Hier werde ich hoffentlich meine Position klarstellen.
Das zu NULL = NULL
bewerten FALSE
ist falsch. Hacker und Mister haben richtig geantwortet NULL
. Hier ist warum. Dewayne Christensen schrieb mir in einem Kommentar an Scott Ivey :
Da es Dezember ist, verwenden wir ein saisonales Beispiel. Ich habe zwei Geschenke unter dem Baum. Jetzt sagst du mir, ob ich zwei davon habe oder nicht.
Sie können unterschiedlich oder gleich sein, man weiß es nicht, bis man beide Geschenke öffnet. Wer weiß? Sie lud zwei Menschen, die einander nicht kennen und beide haben Sie das gleiche Geschenk gemacht - selten, aber nicht unmöglich § .
Die Frage: Sind diese beiden UNBEKANNTEN gleich (gleich, =)? Die richtige Antwort lautet: UNBEKANNT (dhNULL
).
Dieses Beispiel sollte zeigen, dass ".. ( false
oder null
, abhängig von Ihrem System) .." eine richtige Antwort ist - es ist nicht nur NULL
in 3VL richtig (oder ist es in Ordnung, ein System zu akzeptieren, das falsche Antworten gibt? )
Eine richtige Antwort auf diese Frage muss diese beiden Punkte hervorheben:
- Drei-Werte-Logik (3VL) ist nicht intuitiv (siehe unzählige andere Fragen zu diesem Thema auf Stackoverflow und in anderen Foren, um sicherzugehen);
- SQL-basierte DBMS respektieren häufig nicht einmal 3VL, sie geben manchmal falsche Antworten (wie das ursprüngliche Poster behauptet, SQL Server in diesem Fall).
Also wiederhole ich: SQL zwingt nicht dazu, die reflexive Eigenschaft der Gleichheit zu interpretieren, die besagt, dass:
for any x, x = x
§§ (im Klartext: Unabhängig vom Universum des Diskurses ist ein "Ding" immer gleich sich selbst ).
.. in einem 3VL ( TRUE
, FALSE
, NULL
). Die Erwartung der Menschen 2VL entsprechen würde ( TRUE
, FALSE
, die auch in SQL gilt für alle anderen Werte), dh x = x
bewerten immer TRUE
, für jeden möglichen Wert von x - ohne Ausnahme.
Beachten Sie auch, dass NULL -Werte gültige Nichtwerte sind " sind (wie ihre Apologeten dies vorgeben), die man als Attributwerte (??) als Teil von Beziehungsvariablen zuweisen kann. Sie sind also akzeptable Werte für jeden Typ (Domäne), nicht nur für den Typ der logischen Ausdrücke.
Und das war mein Punkt : NULL
Als Wert ist es ein "seltsames Tier". Ohne Euphemismus sage ich lieber: Unsinn .
Ich denke, dass diese Formulierung viel klarer und weniger umstritten ist - entschuldigen Sie meine schlechten Englischkenntnisse.
Dies ist nur eines der Probleme von NULL. Vermeiden Sie sie nach Möglichkeit besser.
§ Wir sind hier besorgt über Werte , daher ist die Tatsache, dass die beiden Geschenke immer zwei verschiedene physische Objekte sind, kein gültiger Einwand. Wenn Sie nicht überzeugt sind, dass es mir leid tut, ist dies nicht der richtige Ort, um den Unterschied zwischen Wert- und "Objekt" -Semantik zu erklären (Relationale Algebra hat von Anfang an Wertesemantik - siehe Codds Informationsprinzip; ich denke, dass einige SQL DBMS-Implementierer dies nicht tun kümmert sich nicht einmal um eine gemeinsame Semantik).
§§ Meines Wissens ist dies ein Axiom, das seit der Antike akzeptiert wurde (in der einen oder anderen Form, aber immer in einer 2VL interpretiert), und das genau deshalb , weil es so intuitiv ist. 3VLs (ist in Wirklichkeit eine Familie von Logik) ist eine viel neuere Entwicklung (aber ich bin mir nicht sicher, wann sie zum ersten Mal entwickelt wurde).
Randbemerkung: wenn jemand vorstellen Bottom , Einheit und Optionstypen als Versuche SQL NULL - Werte zu rechtfertigen, werde ich erst nach einer sehr detaillierten Prüfung überzeugt sein , das wird zeigt, wie SQL - Implementierungen mit NULL - Werten ein Sound - Typ - System und können klären, schließlich, Was sind NULL-Werte (diese "Werte-nicht-ganz-Werte") wirklich?
Im Folgenden werde ich einige Autoren zitieren. Jeder Fehler oder jede Auslassung stammt wahrscheinlich von mir und nicht von den ursprünglichen Autoren.
Joe Celko über SQL NULLs
Ich sehe Joe Celko oft in diesem Forum zitiert. Anscheinend ist er hier ein sehr angesehener Autor. Also sagte ich mir: "Was hat er über SQL NULLs geschrieben? Wie erklärt er NULLs zahlreiche Probleme?". Einer meiner Freunde hat eine E-Book-Version von Joe Celkos SQL für Smarties: Advanced SQL Programming, 3. Ausgabe . Mal schauen.
Zunächst das Inhaltsverzeichnis. Was mir am meisten auffällt, ist die Häufigkeit, mit der NULL erwähnt wird, und in den unterschiedlichsten Kontexten:
3.4 Arithmetik und NULL-
Werte 109 3.5 Konvertieren von Werten in und von NULL 110
3.5.1 NULLIF () -Funktion 110
6 NULL-Werte: Fehlende Daten in SQL 185
6.4 Vergleichen von NULL- Werten 190
6.5 NULL-Werten und Logik 190
6.5.1 NULL-Werten in Unterabfrage-Prädikaten 191
6.5.2 Standard SQL-Lösungen 193
6.6 Mathematik und NULL-Werte 193
6.7 Funktionen und NULL-Werte 193
6.8 NULL-Werte und Host-Sprachen 194
6.9 Entwurfsempfehlung für
NULL-Werte 195
6.9.1 Vermeiden von
NULL-Werten in den Host-Programmen 197 6.10 Hinweis zu mehreren NULL-Werten 198
10.1 IS NULL-Prädikat 241
10.1. 1 NULL-Quellen 242
...
und so weiter. Es klingelt für mich "böser Sonderfall".
Ich werde auf einige dieser Fälle mit Auszügen aus diesem Buch eingehen und versuchen, mich aus urheberrechtlichen Gründen auf das Wesentliche zu beschränken. Ich denke, diese Zitate fallen unter die "Fair Use" -Doktrin und können sogar zum Kauf des Buches anregen - daher hoffe ich, dass sich niemand beschweren wird (andernfalls muss ich das meiste, wenn nicht alle, löschen). Darüber hinaus werde ich aus demselben Grund keine Code-Schnipsel melden. Das tut mir leid. Kaufen Sie das Buch, um mehr über datengesteuertes Denken zu erfahren.
Seitenzahlen in Klammern im Folgenden.
NICHT NULL Einschränkung (11)
Die wichtigste Spaltenbeschränkung ist NOT NULL, wodurch die Verwendung von NULL in einer Spalte verboten wird. Verwenden Sie diese Einschränkung routinemäßig und entfernen Sie sie nur, wenn Sie einen guten Grund haben. Dies hilft Ihnen, die Komplikationen von NULL-Werten zu vermeiden , wenn Sie Abfragen zu den Daten durchführen.
Es ist kein Wert ; Es ist eine Markierung, die eine Stelle enthält, an die ein Wert gehen könnte.
Wieder dieser "Wert aber nicht ganz ein Wert" Unsinn. Der Rest scheint mir ziemlich vernünftig.
(12)
Kurz gesagt, NULL-Werte verursachen in SQL viele unregelmäßige Funktionen, auf die wir später noch eingehen werden. Ihre beste Wette ist es, sich die Situationen und Regeln für NULL-Werte zu merken, wenn Sie sie nicht vermeiden können.
Apropos von SQL, NULLs und unendlich:
(104) KAPITEL 3: NUMERISCHE DATEN IN SQL
SQL hat das IEEE-Modell für Mathematik aus mehreren Gründen nicht akzeptiert.
...
Wenn die IEEE-Regeln für Mathematik in SQL zulässig wären, würden wir Typkonvertierungsregeln für unendlich und eine Möglichkeit benötigen, einen unendlich exakten numerischen Wert nach der Konvertierung darzustellen. Die Leute haben genug Probleme mit NULL, also lasst uns nicht dorthin gehen.
SQL-Implementierungen haben nicht entschieden, was NULL in bestimmten Kontexten wirklich bedeutet:
3.6.2 Exponentialfunktionen (116)
Das Problem ist, dass Logarithmen undefiniert sind, wenn (x <= 0). Einige SQL-Implementierungen geben eine Fehlermeldung zurück, andere NULL und DB2 / 400. Version 3, Version 1, gab als Ergebnis * NEGINF (kurz für „negative Infinity“) zurück.
Joe Celko zitiert David McGoveran und CJ Datum:
6 NULL: Fehlende Daten in SQL (185)
In ihrem Buch A Guide to Sybase und SQL Server sagten David McGoveran und CJ Date: „Nach Ansicht dieses Autors sind NULL-Werte, zumindest wie sie derzeit in SQL definiert und implementiert sind, weitaus schwieriger als sie es wert sind und vermieden werden sollten. Sie zeigen ein sehr seltsames und inkonsistentes Verhalten und können eine reichhaltige Quelle für Fehler und Verwirrung sein. (Bitte beachten Sie, dass diese Kommentare und Kritikpunkte für jedes System gelten, das SQL-artige NULL-Werte unterstützt, nicht nur für SQL Server.) ”
NULL als Drogenabhängigkeit :
(186/187)
Im Rest dieses Buches werde ich Sie auffordern, sie nicht zu verwenden , was widersprüchlich erscheinen mag, aber nicht. Stellen Sie sich einen NULL als Droge vor. Verwenden Sie es richtig und es funktioniert für Sie, aber missbrauchen Sie es und es kann alles ruinieren. Ihre beste Richtlinie ist es, NULL-Werte zu vermeiden, wenn Sie können, und sie ordnungsgemäß zu verwenden, wenn Sie müssen.
Mein einzigartiger Einwand hier ist, "sie richtig zu verwenden", was schlecht mit bestimmten Implementierungsverhalten interagiert.
6.5.1 NULL in Unterabfrageprädikaten (191/192)
Die Leute vergessen, dass eine Unterabfrage oft einen Vergleich mit einem NULL verbirgt. Betrachten Sie diese beiden Tabellen:
...
Das Ergebnis ist leer. Dies ist nicht intuitiv , aber richtig.
(Separator)
6.5.2 Standard-SQL-Lösungen (193)
SQL-92 löste einige der 3VL-Probleme (dreiwertige Logik) durch Hinzufügen eines neuen Prädikats der Form:
<Suchbedingung> IST [NICHT] WAHR | FALSE | UNBEKANNT
UNBEKANNT ist jedoch eine Quelle von Problemen an sich, so dass CJ Date in seinem unten zitierten Buch in Kapitel 4.5 empfiehlt . Vermeiden von Nullen in SQL :
- Verwenden Sie das Schlüsselwort UNKNOWN in keinem Kontext.
Lesen Sie "ASIDE" auf UNKNOWN, ebenfalls unten verlinkt.
6.8 NULL-Werte und Host-Sprachen (194)
Sie sollten jedoch wissen, wie NULL-Werte behandelt werden, wenn sie an ein Host-Programm übergeben werden müssen. Keine Standardhostsprache, für die eine Einbettung definiert ist, unterstützt NULL-Werte. Dies ist ein weiterer guter Grund, diese nicht in Ihrem Datenbankschema zu verwenden.
(Separator)
6.9 Entwurfsempfehlung für NULL (195)
Es ist eine gute Idee, wenn möglich, alle Basistabellen mit NOT NULL-Einschränkungen für alle Spalten zu deklarieren. NULL-Werte verwirren Leute, die SQL nicht kennen, und NULL-Werte sind teuer.
Einwand: NULL verwirrt auch Leute, die SQL gut kennen, siehe unten.
(195)
NULL-Werte sollten in AUSLÄNDISCHEN SCHLÜSSELN vermieden werden. SQL ermöglicht diese Beziehung "Vorteil des Zweifels", kann jedoch zu einem Informationsverlust bei Abfragen führen, die Verknüpfungen betreffen. Wenn Sie beispielsweise einen Teilenummerncode im Inventar angeben, der von einer Auftragstabelle als AUSLÄNDISCHER SCHLÜSSEL bezeichnet wird, haben Sie Probleme, eine Liste der Teile mit NULL zu erhalten. Dies ist eine obligatorische Beziehung; Sie können kein nicht bestehendes Teil bestellen.
(Separator)
6.9.1 Vermeiden von NULL-Werten aus den Host-Programmen (197)
Mit etwas Programmierdisziplin können Sie vermeiden, NULL-Werte aus den Host-Programmen in die Datenbank aufzunehmen.
...
- Bestimmen der Auswirkung fehlender Daten auf Programmierung und Berichterstellung:
Numerische Spalten mit NULL-Werten sind ein Problem, da Abfragen mit Aggregatfunktionen irreführende Ergebnisse liefern können.
(Separator)
(227)
Die Summe () einer leeren Menge ist immer NULL. Einer der häufigsten Programmierfehler bei Verwendung dieses Tricks ist das Schreiben einer Abfrage, die mehr als eine Zeile zurückgeben kann. Wenn Sie nicht darüber nachgedacht haben, haben Sie vielleicht das letzte Beispiel geschrieben als: ...
(Separator)
10.1.1 NULL-Quellen (242)
Es ist wichtig, sich daran zu erinnern, wo NULL-Werte auftreten können. Sie sind mehr als nur ein möglicher Wert in einer Spalte . Aggregatfunktionen für leere Mengen, OUTER JOINs, arithmetische Ausdrücke mit NULL-Werten und OLAP-Operatoren geben alle NULL-Werte zurück. Diese Konstrukte werden in VIEWs häufig als Spalten angezeigt.
(Separator)
(301)
Ein weiteres Problem mit NULL-Werten tritt auf, wenn Sie versuchen, IN-Prädikate in EXISTS-Prädikate zu konvertieren.
(Separator)
16.3 Die ALL-Prädikat- und Extrema-Funktionen (313)
Es ist zunächst nicht intuitiv, dass diese beiden Prädikate in SQL nicht identisch sind:
...
Sie müssen sich jedoch die Regeln für die Extrema-Funktionen merken - sie löschen alle NULL-Werte, bevor die größeren oder kleinsten Werte zurückgegeben werden. Das ALL-Prädikat löscht keine NULL-Werte, sodass Sie sie in den Ergebnissen abrufen können.
(Separator)
(315)
Die Definition im Standard ist jedoch negativ formuliert, so dass NULL-Werte den Vorteil des Zweifels erhalten. ...
Wie Sie sehen können, ist es eine gute Idee, NULL-Werte in EINZIGARTIGEN Einschränkungen zu vermeiden.
Diskussion der GRUPPE VON:
NULL-Werte werden so behandelt, als wären sie alle gleich und bilden eine eigene Gruppe. Jede Gruppe wird dann in einer neuen Ergebnistabelle, die die alte ersetzt, auf eine einzelne Zeile reduziert.
Dies bedeutet, dass für die GROUP BY-Klausel NULL = NULL nicht wie in 3VL als NULL ausgewertet wird, sondern als TRUE.
SQL-Standard ist verwirrend:
ORDER BY und NULLs (329)
Ob ein Sortierschlüsselwert, der NULL ist, als größer oder kleiner als ein Nicht-NULL-Wert angesehen wird, ist implementierungsdefiniert, aber ...
... Es gibt SQL-Produkte, die dies so oder so tun.
Im März 1999 stellte Chris Farrar eine Frage eines seiner Entwickler, die ihn veranlasste, einen Teil des SQL-Standards zu untersuchen , den ich zu verstehen glaubte . Chris fand einige Unterschiede zwischen dem allgemeinen Verständnis und dem tatsächlichen Wortlaut der Spezifikation .
Und so weiter. Ich denke ist genug von Celko.
CJ-Datum für SQL-NULL-Werte
CJ Date ist radikaler in Bezug auf NULL-Werte: Vermeiden Sie NULL-Werte in SQL, Punkt. Tatsächlich trägt Kapitel 4 seiner SQL- und relationalen Theorie: Wie schreibe ich genauen SQL-Code den Titel "NO DUPLICATES, NO NULLS" mit den Unterkapiteln
"4.4 Was stimmt nicht mit Nullen?" und "4.5 Vermeiden von Nullen in SQL" (folgen Sie dem Link: Dank Google Books können Sie einige Seiten online lesen).
Fabian Pascal über SQL NULLs
Aus seinen praktischen Fragen im Datenbankmanagement - Eine Referenz für den denkenden Praktiker (keine Online-Auszüge, sorry):
10.3 Praktische Implikationen
10.3.1 SQL-NULL-Werte
... SQL leidet unter den Problemen, die 3VL inhärent sind, sowie unter vielen Macken, Komplikationen, Gegenintuitivität und direkten Fehlern [10, 11]; unter ihnen sind die folgenden:
- Aggregatfunktionen (z. B. SUM (), AVG ()) ignorieren NULL-Werte (außer COUNT ()).
- Ein skalarer Ausdruck in einer Tabelle ohne Zeilen wird falsch als NULL anstelle von 0 ausgewertet.
- Der Ausdruck "NULL = NULL" ergibt NULL, ist jedoch in SQL ungültig. ORDER BY behandelt NULL-Werte jedoch als gleich (was auch immer vor oder nach "regulären" Werten steht, bleibt dem DBMS-Anbieter überlassen).
- Der Ausdruck "x IST NICHT NULL" ist nicht gleich "NICHT (x IST NULL)", wie dies in 2VL der Fall ist.
...
Alle kommerziell implementierten SQL-Dialekte folgen diesem 3VL-Ansatz und zeigen daher nicht nur diese Probleme, sondern auch spezifische Implementierungsprobleme, die je nach Produkt unterschiedlich sind .