Der Wert »NULL« in SQL
Obwohl man die Verwendung eines NULL-Wertes aus der Sicht der Theorie der relationalen Datenbanken ablehnen könnte, kommt der NULL-Wert in SQL in der Praxis in manchen Fällen vor und wird deswegen hier behandelt.
Der Wert »NULL«
Der Wert »NULL« ist nicht mit der leeren Zeichenfolge «''», der Zahl «0» oder der Zeichenfolge «'NULL'» zu verwechseln. Es handelt sich vielmehr um einen speziellen Wert, der keiner Zeichenfolge gleich ist. Zur besseren Unterscheidung drucken wir diesen Wert deswegen hier oft in einer speziellen Farbe (Rot).
- Zitat aus ISO 9075-1
- 3.1.1.12 null value
- special value that is used to indicate the absence of any data value
- Aussprachehinweis für das englische Wort “null ”
- null nʌl – (Angaben aus verschiedenen Quellen: nʌəl (sg), ⌊ˈnʌ̮ɫː⌋ (sc), nʌl (d), ˈn əl (n) (vgl. signal 'sɪɡ nəl))
Man kann die ISO -Definition dadurch präzisieren, daß man eine Unterscheidung zwischen „Datenwerten“ und „Werten“ einführt, bei der alle Datenwerte auch Werte sind und »NULL« der einzige Wert ist, der kein Datenwert ist und die Abwesenheit eines Datenwertes kennzeichnet.
In seinem Werk “The Relational Model for Database Management: Version 2 ” sieht E. F. Codd mehrere verschiedene NULL-Werte vor und nennt sie „markierte Werte“ oder „Marken“ (im Sinne von „als fehlend oder nicht-anwendbar markierte Werten“). Insbesondere soll die Bezeichnung „Marke“ die Bezeichnung „Wert“ vermeiden. Ein Wert, der fehlt, aber den die Entität grundsätzlich haben könnte (wie der Name der Ehefrau eines Verheirateten), ist „A-markiert“; ein Wert der fehlt, und den die Entität nicht haben kann (wie der Name der Ehefrau eines Unverheirateten), ist „I-markiert“; daneben kann es auch Werte geben, die fehlen, aber weder A- noch I-markiert sind.
Das Wert »NULL« und die leere Zeichenfolge »''«
Bei einigen real-existierenden Datenbankprodukten wird der Wert »NULL« mit der leeren Zeichenfolge »''« gleichgesetzt. Dies ist aber so nicht in SQL vorgesehen und auch nicht zu empfehlen.
Eine Tabelle könnte beispielsweise Endungen von Wortformen enthalten. Zerlegt man die Verbform „denkt“ in einen Stamm „denk“ und eine Endung „-t“, so hat der Imperativ „denk!“ die Nullendung (leere Endung) „“ (also gar keine Zeichen als Endung). Um eine solche leere Endung in eine Tabelle einzutragen, wird dann die entsprechende leere Zeichenfolge »« verwendet (in SQL mit dem Literal »''« notiert). Das Eintragen des Wertes »NULL« würde hingegen bedeuten, daß über die Endung keine Aussage gemacht werden soll. Daher ist es nötig, daß man die leere Zeichenfolge »« vom Wert »NULL« unterscheiden kann.
In der folgenden Tabelle sollte die Endung im Tupel 526 die leere Zeichenfolge sein und nicht der Wert »NULL«.
- Konjugation eines Verbs
Verb
Tupel Wort Modus Numerus Stamm Endung
526 4138 Imperativ Singular denk
527 4138 Imperativ Singular denk e
528 4138 Imperativ Plural denk t
Die Semantik des Wertes »NULL«
Der Wert »NULL« in einer Zelle bedeutet, daß diese Zelle praktisch nicht existiert.
Man kann die Bedeutung des Wertes an einem einfachen Bespiel illustrieren. Eine Tabelle soll die additiven Grundfarben darstellen. Die Tabelle A hat dann die gleiche Bedeutung wie die Tabelle B.
- Tabelle A
Rot
Grün
NULL
Blau- Tabelle A
Rot
Grün
Blau
Da der Wert »NULL« die Abwesenheit von Information kennzeichnet, sollte nicht vereinbart werden, daß dieser Wert in einer bestimmten Spalte irgendeine andere Information übermittelt als „nicht festgelegt“.
Statt dessen sollte zur Speicherung der Information, ob eine Person noch lebt, bei Bedarf eine extra Spalte für diese Information angelegt werden, in welche dann beispielweise die Texte »ja« oder »nein« (oder eventuell auch »unbekannt«) geschrieben werden könnten, um festzuhalten, ob jemand noch lebt.
Beispielsweise sollte der NULL-Wert als Todesdatum einer Person, nicht so interpretiert werden, daß diese Person noch lebt. Würde man dies tun, gäbe es keinen Wert mehr, der verwendet werden kann, wenn es dann einmal tatsächlich unbekannt ist, ob jemand noch lebt.
- Normalisierte Darstellung
Person
Person Vorname Nachname Todesdatum
0 Laura Pfeiffer 2012-07-08
1 Liam Wolff 1951-01-07
2 Lina Arnold NULL
3 Elias Sauer NULL
4 Levi Voigt 1961-11-12
5 Julia Thomas 1978-02-14
Oben sollte man die Bedeutung des Nullwertes in der Spalte »Todesdatum« nur als „Über das Todesdatum ist keine Information in der Datenbank vorhanden“ vereinbaren und interpretieren, und nicht als „Die Person lebt noch.“.
Das NULL-Literal
Das NULL-Literal ist eine Schreibweise für den Wert »NULL« und lautet »NULL«. Im Gegensatz zur Zeichenfolge »'NULL'« wird es also ohne Apostrophe notiert.
Das explizite Einfügen eines NULL-Wertes
Beim Einfügen einer Zeile kann der Wert »NULL« explizit durch Verwendung seines Literals »NULL« eingefügt werden.
- Skript (MySQL )
DROP SCHEMA S; CREATE SCHEMA S; USE S;
CREATE TABLE LISTE ( I VARCHAR ( 255 ));
SELECT * FROM LISTE;
INSERT INTO LISTE ( I ) VALUES ( '0' );
INSERT INTO LISTE ( I ) VALUES ( NULL );
INSERT INTO LISTE ( I ) VALUES ( '2' );
SELECT * FROM LISTE;+------+
| I |
+------+
| 0 |
| NULL |
| 2 |
+------+
3 rows in set
Das implizite Einfügen eines NULL-Wertes
Wenn beim Anlegen einer Zeile der Wert für eine Spalte nicht angegeben wird, dann wird als Wert jener Spalte in der Regel »NULL« verwendet.
- Skript (MySQL )
DROP SCHEMA S; CREATE SCHEMA S; USE S;
CREATE TABLE LISTE ( I VARCHAR ( 255 ), DE VARCHAR ( 255 ));
SELECT * FROM LISTE;
INSERT INTO LISTE ( I, DE ) VALUES ( '0', 'NULL' );
INSERT INTO LISTE ( I ) VALUES ( '1' );
INSERT INTO LISTE ( I, DE ) VALUES ( '2', 'ZWEI' );
SELECT * FROM LISTE;+------+------+
| I | DE |
+------+------+
| 0 | NULL |
| 1 | NULL |
| 2 | ZWEI |
+------+------+
Verwirrenderweise enthält die Spalte »DE« einmal die Zeichenfolge »NULL« und einmal den NULL-Wert »NULL«.
Das Selektieren eines NULL-Wertes
Um nach Gleichheit mit einem NULL-Wert zu selektieren, kann nicht »= NULL« verwendet werden, vielmehr muß »IS NULL« verwendet werden.
- Skript (MySQL, C99)
SELECT * FROM LISTE WHERE DE = NULL;
Empty set
- Skript (MySQL, C99)
SELECT * FROM LISTE WHERE DE IS NULL;
+------+------+
| I | DE |
+------+------+
| 1 | NULL |
+------+------+1 row in set
- Skript (MySQL, C99)
SELECT * FROM LISTE WHERE DE = 'NULL';
+------+------+
| I | DE |
+------+------+
| 0 | NULL |
+------+------+
1 row in set
Mit »IS NOT NULL« kann verlangt werden, daß ein Datenwert vorhanden ist.
- Skript (MySQL, C99)
SELECT * FROM LISTE WHERE DE IS NOT NULL;
+------+------+
| I | DE |
+------+------+
| 0 | NULL |
| 2 | ZWEI |
+------+------+2 rows in set
Das Verbieten von NULL-Werten
Wenn bei Anlegen einer Tabelle für eine Spalte »VARCHAR ( 255 ) NOT NULL« statt »VARCHAR ( 255 )« verwendet wird, dann kann für diese Spalte kein NULL-Wert eingetragen werden.
- Skript (MySQL )
DROP SCHEMA S; CREATE SCHEMA S; USE S;
CREATE TABLE LISTE ( I VARCHAR ( 255 ) NOT NULL );
SELECT * FROM LISTE;
INSERT INTO LISTE ( I ) VALUES ( '0' );
INSERT INTO LISTE ( I ) VALUES ( NULL );ERROR 1048 (23000): Column 'I' cannot be null
Mit »DESCRIBE« kann eine Tabelle mit Informationen über die Spalten einer Tabelle ausgegeben werden. So kann angezeigt werden, ob eine Spalte den Wert »NULL« enthalten darf.
- Skript (MySQL )
DESCRIBE LISTE;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| I | varchar(255) | NO | | NULL | |
+-------+--------------+------+-----+---------+-------+DROP SCHEMA S; CREATE SCHEMA S; USE S;
CREATE TABLE LISTE ( I VARCHAR ( 255 ));
DESCRIBE LISTE;+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| I | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
Das Festlegen eines anderen Fehlwertes
Mit »DEFAULT« kann ein anderer Fehlwert als »NULL« für eine Spalte festgelegt werden.
- Skript (MySQL )
DROP SCHEMA S; CREATE SCHEMA S; USE S;
CREATE TABLE LISTE ( I VARCHAR ( 255 ) DEFAULT 'WORT' );
INSERT INTO LISTE ( I ) VALUES ( '0' );
INSERT INTO LISTE ( ) VALUES ( );
SELECT * FROM LISTE;+------+
| I |
+------+
| 0 |
| WORT |
+------+2 rows
DESCRIBE LISTE;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| I | varchar(255) | YES | | WORT | |
+-------+--------------+------+-----+---------+-------+
Möglichkeiten zur Vermeidung der Verwendung von »NULL« ⃗
Hier seien zwei schon behandelte Möglichkeiten zur Vermeidung eines speziellen NULL-Wertes noch einmal genannt:
- Man kann Werte, die nur bei manchen Datensätzen vorhanden sind, als eine 1:n-Beziehung auffassen, bei der n gleich 0 oder gleich 1 ist. Entsprechend können solche Werte dann in einer zusätzlichen Detailtabelle gehalten werden.
- Um das Fehlen einer Information in einer Zelle zu kennzeichnen, ist der spezielle NULL-Wert nicht unbedingt verkehrt, da er in SQL genau dafür vorgesehen ist. Falls es aber mehrere Arten des Fehlens geben sollte, die in Frage kommen, könnten spezielle Zeichenfolgen dafür vereinbart werden (in der Dokumentation oder mit einer Detailtabelle), die als normale Datenwerte nicht vorkommen können. (Wenn man das Domänenprinzip streng beachten will, müßte man hier zwei Detailtabellen verwenden – eine für normale Werte, beispielsweise Rufnummern, und eine für Metawerte, welche die Art des Fehlens der Information näher beschreiben.)