Was ist NULLNULL wird verwendet, um fehlende Werte oder unbekannte Daten darzustellen, nicht einen Wert eines bestimmten Typs. Der NULL-Wert in der Datentabelle bedeutet, dass das Feld, in dem sich der Wert befindet, leer ist. Ein Feld mit einem NULL-Wert hat keinen Wert. Es ist besonders wichtig zu verstehen, dass der NULL-Wert nichts mit 0 oder einer leeren Zeichenfolge zu tun hat. Zwei Arten von NULLDiese Aussage erscheint Ihnen möglicherweise seltsam, da es in SQL nur eine Art von NULL gibt. Bei der Diskussion von NULL denken wir jedoch im Allgemeinen an zwei Typen: „unbekannt“ und „nicht zutreffend, nicht zutreffend“. Nehmen wir das Beispiel: „Ich weiß nicht, welche Augenfarbe eine Person hat, die eine Sonnenbrille trägt.“ Die Augen dieser Person haben definitiv eine Farbe, aber wenn sie die Brille nicht absetzt, wissen andere nicht, welche Farbe ihre Augen haben. Dies nennt man das Unbekannte. Und „Ich weiß nicht, welche Augenfarbe der Kühlschrank hat“ lautet „Nicht zutreffend“. Da Kühlschränke keine Augen haben, gilt die Eigenschaft „Augenfarbe“ für Kühlschränke nicht. Aussagen wie „die Farbe der Augen des Kühlschranks“ sind ebenso bedeutungslos wie Aussagen wie „das Volumen eines Kreises“ oder „die Anzahl der Geburten, die ein Mann zur Welt bringt“. Normalerweise sind wir es gewohnt, „Ich weiß nicht“ zu sagen, aber es gibt viele Arten von „Ich weiß nicht“. NULL entspricht in diesem Fall von „nicht zutreffend“ in der Semantik eher „bedeutungslos“ als „unbestimmt“. Um es zusammenzufassen: „Unbekannt“ bedeutet „wir wissen es jetzt zwar nicht, können es aber wissen, wenn bestimmte Bedingungen erfüllt sind“; und „Nicht zutreffend“ bedeutet „wir können es nicht wissen, egal wie sehr wir es versuchen.“ Der erste, der diese Klassifizierung vornahm, war EF Codd, der Erfinder des relationalen Modells. Das Folgende ist seine Klassifizierung von „verlorenen Informationen“ Warum muss es als „IS NULL“ statt als „= NULL“ geschrieben werden?Ich glaube, dass diese Verwirrung bei vielen Leuten herrscht, insbesondere bei denen, die gerade SQL gelernt haben. Betrachten wir einen konkreten Fall und gehen davon aus, dass wir die folgende Tabelle und die folgenden Daten haben Tabelle löschen, wenn t_sample_null vorhanden ist; CREATE TABLE t_sample_null ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primärschlüssel automatisch inkrementieren', Name VARCHAR (50) NICHT NULL KOMMENTAR 'Name', Bemerkung VARCHAR(500) COMMENT 'Bemerkungen', Primärschlüssel (ID) ) KOMMENTAR 'NULL Beispiel'; INSERT INTO t_sample_null(Name, Bemerkung) VALUES('zhangsan', 'Zahl'),('Zahl', NULL); Wir möchten die Datensätze mit NULL-Kommentaren abfragen (NULL ist kein korrekter Begriff, aber wir sind im Alltag daran gewöhnt, Einzelheiten siehe unten). Wie fragt man ab? Viele Anfänger schreiben das folgende SQL: -- SQL meldet keinen Fehler, aber es können keine Ergebnisse gefunden werden. SELECT * FROM t_sample_null WHERE comment = NULL; Bei der Ausführung tritt kein Fehler auf, aber wir können das gewünschte Ergebnis nicht finden. Warum ist das so? Lassen wir diese Frage zunächst beiseite und schauen wir uns die nächste an Dreiwertige LogikDiese dreiwertige Logik ist keine ternäre Operation, sondern bezieht sich auf drei logische Werte. Manche Leute haben vielleicht Zweifel. Gibt es nicht nur wahre und falsche logische Werte? Woher kommt der dritte? Dabei müssen wir auf die Umgebung achten, in der wir uns befinden. In gängigen Programmiersprachen (C, JAVA, Python, JS usw.) gibt es tatsächlich nur zwei logische Werte, in SQL jedoch einen dritten logischen Wert: unbekannt. Dies ähnelt dem, was wir normalerweise sagen: Richtig, falsch, ich weiß nicht. Der logische Wert „unbekannt“ und „UNKNOWN“, eine Form von NULL, sind unterschiedliche Dinge. Ersterer ist ein eindeutiger boolescher logischer Wert, während Letzterer weder ein Wert noch eine Variable ist. Um sie leicht unterscheiden zu können, werden Erstere durch die Kleinbuchstaben „unknown“ und Letztere durch die Großbuchstaben „UNKNOWN“ dargestellt. Um Ihnen den Unterschied zwischen den beiden zu verdeutlichen, betrachten wir eine einfache Gleichung wie x=x. Wenn x ein unbekannter logischer Wert ist, wird x=x als wahr betrachtet, und wenn x UNBEKANNT ist, wird es als unbekannt betrachtet. -- Dies ist ein eindeutiger logischer Wertvergleich unbekannt = unbekannt → wahr -- Dies entspricht NULL = NULL UNBEKANNT = UNBEKANNT → unbekannt Logische Wertetabelle der dreiwertigen LogikNICHT UND ODER Der blaue Teil in der Abbildung ist die Operation, die nur in der dreiwertigen Logik vorkommt und in der zweiwertigen Logik nicht existiert. Alle anderen SQL-Prädikate können aus diesen drei logischen Operationen zusammengesetzt werden. In diesem Sinne kann man sagen, dass diese logischen Tabellen die Matrix von SQL sind. Bei NOT ist es leicht zu merken, weil die Tabelle der logischen Werte relativ einfach ist. Bei AND und OR ist es jedoch sehr schwierig, sich alle zu merken, da es viele logische Werte gibt, die kombiniert werden können. Um es leichter zu merken, beachten Sie bitte, dass zwischen diesen drei logischen Werten die folgende Prioritätsreihenfolge gilt. UND-Fall: falsch > unbekannt > wahr ODER Situation: wahr > unbekannt > falsch Der logische Wert mit der höheren Priorität bestimmt das Berechnungsergebnis. Beispielsweise „wahr UND unbekannt“. Da „unbekannt“ eine höhere Priorität hat, ist das Ergebnis „unbekannt“. Wenn es wahr ODER unbekannt ist, ist das Ergebnis wahr, da wahr eine höhere Priorität hat. Wenn Sie sich diese Reihenfolge merken, können Sie dreiwertige logische Operationen leichter durchführen. Es ist wichtig, sich daran zu erinnern, dass, wenn eine UND-Operation Unbekanntes enthält, das Ergebnis definitiv nicht wahr sein wird (umgekehrt, wenn das Ergebnis der UND-Operation wahr ist, müssen beide an der Operation beteiligten Parteien wahr sein). -- Angenommen, a = 2, b = 5, c = NULL, dann lautet der logische Wert des folgenden Ausdrucks: a < b UND b > c → unbekannt a > b ODER b < c → unbekannt a < b ODER b < c → wahr NICHT (b <> c) → unbekannt „IS NULL“ statt „= NULL“Kommen wir zurück zur Frage: Warum müssen wir „IS NULL“ statt „= NULL“ schreiben? Das Ergebnis eines Vergleichsprädikats auf NULL ist immer unbekannt. Die Abfrageergebnisse umfassen nur Zeilen, bei denen das Beurteilungsergebnis in der WHERE-Klausel wahr ist, und keine Zeilen, bei denen das Beurteilungsergebnis falsch oder unbekannt ist. Nicht nur das Gleichheitszeichen, sondern auch andere Vergleichsprädikate für NULL führen zum gleichen Ergebnis. Unabhängig davon, ob die Bemerkung NULL ist oder nicht, ist das Vergleichsergebnis unbekannt und es wird nie ein Ergebnis zurückgegeben. Die folgenden Formeln werden als unbekannt beurteilt -- Die folgenden Formeln werden als unbekannt beurteilt = NULL > NULL < NULL <> NULL NULL = NULL Warum kann ein Vergleichsprädikat für NULL nie als „wahr“ ausgewertet werden? Dies liegt daran, dass NULL weder ein Wert noch eine Variable ist. NULL ist nur ein Token, das „kein Wert“ bedeutet, und Vergleichsprädikate gelten nur für Werte. Daher ist es sinnlos, ein Vergleichsprädikat auf NULL anzuwenden, das kein Wert ist. Aussagen wie „der Wert der Spalte ist NULL“ oder „NULL-Wert“ sind an sich falsch. Da NULL kein Wert ist, liegt er nicht in der Domäne. Wenn man hingegen NULL als einen Wert betrachtet, dann kann man auch andersherum darüber nachdenken: Um welche Art von Wert handelt es sich? Die Werte in einer relationalen Datenbank müssen von einem bestimmten Typ sein, beispielsweise Zeichen oder Numerisch. Wenn NULL ein Wert ist, muss er also von irgendeinem Typ sein. Es gibt zwei Gründe, warum NULL problemlos als Wert betrachtet wird. Der erste ist, dass NULL in höheren Programmiersprachen als Konstante definiert ist (viele Sprachen definieren es als Ganzzahl 0), was zu unserer Verwirrung führt. Allerdings ist NULL in SQL völlig anders als NULL in anderen Programmiersprachen. Der zweite Grund besteht darin, dass ein Prädikat wie IS NULL aus zwei Wörtern besteht, sodass es für uns einfach ist, IS als Prädikat und NULL als Wert zu behandeln. Insbesondere da es in SQL Prädikate wie IS TRUE und IS FALSE gibt, ist eine entsprechende Analogieschlussfolgerung nicht unangemessen. Aber wie die Bücher zu Standard-SQL die Leute erinnern, sollten wir IS NULL als Prädikat betrachten. Daher ist es möglicherweise angemessener, IS_NULL zu schreiben. Sanfte FalleVergleichen von Prädikaten mit NULLDas Gesetz des ausgeschlossenen Dritten gilt nicht. Das Gesetz des ausgeschlossenen Dritten besagt, dass im selben Denkprozess zwei widersprüchliche Ideen nicht gleichzeitig falsch sein können und eine davon wahr sein muss, d. h. „entweder A oder nicht A“. Angenommen, wir haben eine Studententabelle: t_student Tabelle löschen, wenn t_student vorhanden ist; Tabelle erstellen t_student ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primärschlüssel automatisch inkrementieren', Name VARCHAR (50) NICHT NULL KOMMENTAR 'Name', Alter INT (3) COMMENT 'Alter', Bemerkung VARCHAR(500) NOT NULL DEFAULT '' COMMENT 'Bemerkungen', Primärschlüssel (ID) ) KOMMENTAR ‚Studenteninformationen‘; INSERT INTO t_student(Name, Alter) WERT('zhangsan', 25),('wangwu', 60),('bruce', 32),('yzb', NULL),('boss', 18); Wählen Sie * aus t_student; Das Alter der Daten yzb in der Tabelle ist NULL, was bedeutet, dass das Alter von yzb unbekannt ist. In der realen Welt ist yzb entweder 20 Jahre alt oder nicht 20 Jahre alt, eines von beiden muss der Fall sein. Dies ist zweifellos eine wahre Aussage. Gilt also in der Welt von SQL immer noch das Gesetz des ausgeschlossenen Dritten? Schauen wir uns eine SQL an WÄHLEN SIE * VON t_student WO Alter = 20 ODER Alter <> 20; Sind dies auf den ersten Blick nicht alle Datensätze in der Abfragetabelle? Schauen wir uns die tatsächlichen Ergebnisse an yzb hat es nicht herausgefunden, warum? Lassen Sie es uns analysieren. Das Alter von yzb ist NULL. Dann lauten die Beurteilungsschritte für diesen Datensatz wie folgt: -- 1. Johns Alter ist NULL (unbekanntes NULL!) WÄHLEN * VON t_student WO Alter = NULL ODER Alter <> NULL; -- 2. Nach der Anwendung des Vergleichsprädikats auf NULL ist das Ergebnis unbekannt WÄHLEN * VON t_student WO unbekannt ODER unbekannt; -- 3. Das Ergebnis von unbekannt ODER unbekannt ist unbekannt (siehe die Tabelle der logischen Werte der dreiwertigen Logik). WÄHLEN * VON t_student WO unbekannt; Das Abfrageergebnis der SQL-Anweisung enthält nur die Zeilen, bei denen das Beurteilungsergebnis wahr ist. Damit yzb in den Ergebnissen erscheint, müssen Sie die folgende „dritte Bedingung“ hinzufügen: -- Füge 3 Bedingungen hinzu: Alter ist 20, oder nicht 20, oder Alter ist unbekannt SELECT * FROM t_student WO Alter = 20 ODER Alter <> 20 ODER Alter ist NULL; CASE-Ausdrücke und NULL Der einfache CASE-Ausdruck lautet wie folgt FALL col_1 WENN = 1, DANN 'o' WENN NULL, DANN 'x' ENDE Dieser CASE-Ausdruck gibt niemals × zurück. Dies liegt daran, dass die zweite WHEN-Klausel eine Abkürzung für col_1 = NULL ist. Wie wir wissen, ist der logische Wert dieses Ausdrucks immer unbekannt, und die Beurteilungsmethode des CASE-Ausdrucks ist dieselbe wie die der WHERE-Klausel, die nur Bedingungen mit einem logischen Wert von „true“ erkennt. Die korrekte Schreibweise ist die Verwendung eines CASE-Suchausdrucks wie diesem: FALL, WENN col_1 = 1, DANN 'o' WENN col_1 NULL IST, DANN 'x' ENDE NOT IN und NOT EXISTS sind nicht gleichwertigWenn wir die Leistung von SQL-Anweisungen optimieren, verwenden wir häufig einen Trick: Wir schreiben IN in EXISTS um. Dies ist eine gleichwertige Umschreibung und es gibt kein Problem. Wenn NOT IN jedoch als NOT EXISTS umgeschrieben wird, sind die Ergebnisse möglicherweise nicht dieselben. Nehmen wir ein Beispiel. Wir haben zwei Tabellen: t_student_A und t_student_B, die jeweils Schüler der Klasse A und Klasse B darstellen. Tabelle löschen, wenn t_student_A vorhanden ist; Tabelle erstellen t_student_A ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primärschlüssel automatisch inkrementieren', Name VARCHAR (50) NICHT NULL KOMMENTAR 'Name', Alter INT (3) COMMENT 'Alter', Stadt VARCHAR(50) NOT NULL KOMMENTAR 'Stadt', Bemerkung VARCHAR(500) NOT NULL DEFAULT '' COMMENT 'Bemerkungen', Primärschlüssel (ID) ) KOMMENTAR ‚Studenteninformationen‘; INSERT INTO t_student_A(Name, Alter, Stadt) WERT ('zhangsan', 25, 'Stadt Shenzhen'),('wangwu', 60, 'Stadt Guangzhou'), ('bruce', 32, 'Peking'),('yzb', NULL, 'Shenzhen'), ('Chef', 43, 'Shenzhen City'); Tabelle löschen, wenn t_student_B vorhanden ist; Tabelle erstellen t_student_B ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Primärschlüssel automatisch inkrementieren', Name VARCHAR (50) NICHT NULL KOMMENTAR 'Name', Alter INT (3) COMMENT 'Alter', Stadt VARCHAR(50) NOT NULL KOMMENTAR 'Stadt', Bemerkung VARCHAR(500) NOT NULL DEFAULT '' COMMENT 'Bemerkungen', Primärschlüssel (ID) ) KOMMENTAR ‚Studenteninformationen‘; INSERT INTO t_student_B(Name, Alter, Stadt) WERT ('Ma Huateng', 45, 'Stadt Shenzhen'),('Ma San', 25, 'Stadt Shenzhen'), ('Jack Ma', 43, 'Hangzhou'),('Robin Li', 41, 'Shenzhen'), („junge Leute“, 25, „Shenzhen“); * VON t_student_B; Anforderung: Abfrage der Schüler der Klasse B, die sich im Alter von den Schülern der Klasse A unterscheiden, die in Shenzhen leben, d. h. Abfrage: Ma Huateng und Li Yanhong. Wie soll dieses SQL geschrieben werden, etwa so? -- Schüler der Klasse B finden, die sich im Alter von den Schülern der Klasse A unterscheiden und in Shenzhen leben? WÄHLEN SIE * VON t_student_B WO Alter NICHT IN ( Wählen Sie Alter aus t_Student_A WO Stadt = 'Shenzhen' ); Schauen wir uns die Ausführungsergebnisse an Wir haben festgestellt, dass das Ergebnis leer war und keine Daten gefunden werden konnten. Warum ist das so? Hier beginnt NULL wieder Probleme zu verursachen. Schauen wir uns Schritt für Schritt an, was passiert. -- 1. Führen Sie eine Unterabfrage aus, um die Altersliste zu erhalten: SELECT * FROM t_student WO Alter NICHT IN (43, NULL, 25); -- 2. Schreiben Sie NOT IN neu, indem Sie NOT und IN äquivalent verwenden WÄHLEN SIE * VON t_student WO NICHT Alter IN (43, NULL, 25); -- 3. Schreiben Sie das Prädikat IN unter Verwendung der OR-Äquivalenz neu WÄHLEN SIE * VON t_student WO NICHT ( (Alter = 43) ODER (Alter = NULL) ODER (Alter = 25) ); -- 4. Verwenden Sie die Gesetze von De Morgan, um SELECT * FROM t_student neu zu schreiben WO NICHT (Alter = 43) UND NICHT (Alter = NULL) UND NICHT (Alter = 25); -- 5. Verwenden Sie <>, um NOT und = umzuschreiben WÄHLEN SIE * VON t_student WO (Alter <> 43) UND (Alter <> NULL) UND (Alter <> 25); -- 6. Nach der Verwendung von <> für NULL ist das Ergebnis unbekannt WÄHLEN SIE * VON t_student WO (Alter <> 43) UND unbekannt UND (Alter <> 25); -- 7. Wenn die UND-Operation Unbekanntes enthält, ist das Ergebnis nicht wahr (siehe die Tabelle der logischen Werte der dreiwertigen Logik). WÄHLEN SIE * VON t_student WO falsch oder unbekannt; Es ist ersichtlich, dass nach einer Reihe von Transformationen kein Datensatz in der WHERE-Klausel als wahr beurteilt wird. Das heißt, wenn in der ausgewählten Spalte der in der NOT IN-Unterabfrage verwendeten Tabelle NULL steht, ist das Abfrageergebnis der gesamten SQL-Anweisung immer leer. Das ist ein schreckliches Phänomen! Um das richtige Ergebnis zu erhalten, müssen wir das EXISTS-Prädikat verwenden -- Korrekte SQL-Anweisung: Ma Huateng und Li Yanhong werden in SELECT * FROM t_student_B B abgefragt WO NICHT EXISTIERT ( Wählen Sie * aus t_Student_A A WO B.Alter = A.Alter UND A.Stadt = 'Shenzhen' ); Die Ausführungsergebnisse sind wie folgt Schauen wir uns nun an, wie diese SQL-Anweisung Zeilen behandelt, bei denen das Alter NULL ist. - 1. Führen Sie eine Vergleichsoperation mit NULL in der Unterabfrage durch, und A.age ist NULL Wählen Sie * aus t_Student_B B WO NICHT EXISTIERT ( Wählen Sie * aus t_Student_A A WHERE B.age = NULL UND A.Stadt = 'Shenzhen' ); -- 2. Nach der Verwendung von "=" für NULL ist das Ergebnis unbekannt Wählen Sie * aus t_Student_B B WO NICHT EXISTIERT ( Wählen Sie * aus t_Student_A A WO unbekannt UND A.Stadt = 'Shenzhen' ); -- 3. Wenn die UND-Operation Unbekanntes enthält, ist das Ergebnis nicht wahr Wählen Sie * aus t_Student_B B WO NICHT EXISTIERT ( Wählen Sie * aus t_Student_A A WHERE falsch oder unbekannt ); -- 4. Die Unterabfrage gibt keine Ergebnisse zurück, daher ist NOT EXISTS wahr Wählen Sie * aus t_Student_B B WO wahr; Mit anderen Worten, yzb wurde als „eine Person behandelt, deren Alter sich von dem aller anderen unterscheidet.“ EXISTS gibt nur „true“ oder „false“ zurück, niemals „unbekannt“. Daher besteht das verwirrende Phänomen, dass IN und EXISTS austauschbar verwendet werden können, NOT IN und NOT EXISTS jedoch nicht. Es gibt noch einige andere Fallstricke, z. B.: qualifizierte Prädikate und NULL, qualifizierte Prädikate und Extremwertfunktionen sind nicht gleichwertig, Aggregatfunktionen und NULL usw. Zusammenfassen1. NULL wird verwendet, um fehlende Werte oder unbekannte Daten darzustellen. Es ist kein Wert eines bestimmten Typs und kann nicht mit Prädikaten verwendet werden. 2. Das Ergebnis der Verwendung eines Prädikats auf NULL ist unbekannt. Wenn Unbekanntes in logische Operationen einbezogen wird, wird SQL nicht wie erwartet ausgeführt. 3. IS NULL ist ein Prädikat, nicht: IS ist das Prädikat, NULL ist der Wert; ähnlich wie IS TRUE und IS FALSE. 4. Um die verschiedenen durch NULL verursachten Probleme zu lösen, besteht die beste Methode darin, NOT NULL-Einschränkungen zur Tabelle hinzuzufügen, um zu versuchen, NULL auszuschließen. Oben finden Sie eine ausführliche Erläuterung der dreiwertigen MySQL-Logik und von NULL. Weitere Informationen zur dreiwertigen MySQL-Logik und zu NULL finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Detaillierte Beschreibung allgemeiner Ereignisse und Methoden von HTML-Text
>>: Verständnis des synchronen oder asynchronen Problems von setState in React
In diesem Artikelbeispiel wird der spezifische Co...
Einführung Kennen Sie wirklich den Unterschied zw...
Jeder qualifizierte Linux-Betriebs- und Wartungsm...
Inhaltsverzeichnis Hintergrund erreichen Ergänzun...
Inhaltsverzeichnis 1. Objekte durch Literalwert e...
FEHLER 1290 (HY000) : Der MySQL-Server wird mit d...
Vorwort Um zum Originalcode kompatibel zu sein, b...
1. Finden Sie heraus, ob MySQL zuvor installiert ...
MySQL Binlog ist ein sehr wichtiges Protokoll in ...
Kürzlich fragte mich ein Freund, ob ich schon ein...
Wenn Server B (172.17.166.11) eingeschaltet oder ...
Die kleinste Planungseinheit in k8s --- pod Im vo...
1. Öffnen Sie Port 2375 Bearbeiten Sie docker.ser...
Portainer ist ein hervorragendes grafisches Verwa...
In diesem Artikel werden hauptsächlich kreisförmi...