it-swarm.com.de

Wann wird NULL verwendet und wann wird eine leere Zeichenfolge verwendet?

Ich interessiere mich hauptsächlich für MySQL und PostgreSQL, aber Sie können im Allgemeinen Folgendes beantworten:

  • Gibt es ein logisches Szenario, in dem es nützlich wäre, eine leere Zeichenfolge von NULL zu unterscheiden?
  • Was wären die Auswirkungen auf die physische Speicherung beim Speichern einer leeren Zeichenfolge als ...

    • NULL?
    • Leerer String?
    • Ein anderes Feld?
    • Irgendein anderer Weg?
87
Maniero

Angenommen, der Datensatz stammt aus einem Formular zum Sammeln von Namens- und Adressinformationen. Zeile 2 der Adresse ist normalerweise leer, wenn der Benutzer nicht in der Wohnung wohnt. Eine leere Zeichenfolge ist in diesem Fall vollkommen gültig. Ich bevorzuge die Verwendung von NULL, um zu bedeuten, dass der Wert unbekannt oder nicht angegeben ist.

Ich glaube nicht, dass der physische Speicherunterschied in der Praxis besorgniserregend ist. Als Datenbankadministratoren haben wir viel größere Fische zum Braten!

67
Larry Coleman

Ich weiß nichts über MySQL und PostgreSQL, aber lassen Sie mich dies etwas allgemein behandeln.

Es gibt ein DBMS, nämlich Oracle, das es nicht erlaubt, seine Benutzer zwischen NULL und '' zu wählen. Dies zeigt deutlich, dass es nicht notwendig ist, zwischen beiden zu unterscheiden. Es gibt einige ärgerliche Konsequenzen:

Sie setzen einen varchar2 auf einen leeren String wie folgt:

Update mytable set varchar_col = '';

folgendes führt zum gleichen Ergebnis

Update mytable set varchar_col = NULL;

Um jedoch die Spalten auszuwählen, in denen der Wert leer oder NULL ist, müssen Sie verwenden

select * from mytable where varchar_col is NULL;

Verwenden von

select * from mytable where varchar_col = '';

ist syntaktisch korrekt, gibt jedoch niemals eine Zeile zurück.

Auf der anderen Seite beim Verketten von Zeichenfolgen in Oracle. NULL-Varchare werden als leere Zeichenfolgen behandelt.

select NULL || 'abc' from DUAL;

ergibt abc. Andere DBMS würden in diesen Fällen NULL zurückgeben.

Wenn Sie explizit ausdrücken möchten, dass ein Wert zugewiesen ist, müssen Sie etwas wie '' verwenden.

Und Sie müssen sich Sorgen machen, ob das Trimmen nicht zu leeren Ergebnissen in NULL führt

select case when ltrim(' ') is null then 'null' else 'not null' end from dual

Es tut.

Betrachten wir nun DBMS, bei dem '' nicht mit NULL identisch ist (z. B. SQL-Server).

Die Arbeit mit '' ist im Allgemeinen einfacher und in den meisten Fällen besteht keine praktische Notwendigkeit, zwischen beiden zu unterscheiden. Eine der Ausnahmen, die ich kenne, ist, wenn Ihre Spalte eine Einstellung darstellt und Sie keine leeren Standardeinstellungen für sie haben. Wenn Sie zwischen '' und NULL unterscheiden können, können Sie ausdrücken, dass Ihre Einstellung leer ist, und vermeiden, dass die Standardeinstellung gilt.

26
bernd_k

Dies hängt von der Domain ab, an der Sie arbeiten. NULL bedeutet das Fehlen eines Wertes (d. h. es gibt kein Wert), während eine leere Zeichenfolge bedeutet, dass es einen Zeichenfolgenwert gibt von Null Länge.

Angenommen, Sie haben eine Tabelle zum Speichern der Daten einer Person und sie enthält eine Gender -Spalte. Sie können die Werte als "Männlich" oder "Weiblich" speichern. Wenn der Benutzer festlegen kann, dass die Geschlechtsdaten nicht angegeben werden sollen, sollten Sie diese als NULL (dh der Benutzer hat den Wert nicht angegeben) und nicht leere Zeichenfolge (da keine vorhanden ist) speichern Geschlecht mit Wert '').

17
Gan

Beachten Sie, dass Sie leere Werte als NULL speichern müssen, wenn Sie ein Feld haben, das nicht erforderlich ist, aber alle vorhandenen Werte eindeutig sein müssen. Andernfalls können Sie nur ein Tupel mit einem leeren Wert in diesem Feld haben.

Es gibt auch einige Unterschiede zu relationaler Algebra und NULL-Werten: NULL! = NULL zum Beispiel.

10

Sie können auch die Kritik von Date an NULL und die Probleme von 3VL in SQL und relationale Theorie (und Rubinsons Kritik an der Kritik von Date, Nullen, dreiwertige Logik und Mehrdeutigkeit in SQL) berücksichtigen: Kritik des Datums kritisieren ).

Beide werden in einem verwandten SO Thread, Optionen zum Entfernen von NULL-fähigen Spalten aus einem DB-Modell referenziert und ausführlich erläutert.

6
Abie

Ein neuer Gedanke, ein großer Einfluss auf Ihre Wahl von NULL/NOT NULL ist, wenn Sie ein Framework verwenden. Ich verwende viel Symfony und die Verwendung von NULL Feldern vereinfacht einige der Code- und Datenprüfungen bei der Bearbeitung der Daten.

Wenn Sie kein Framework verwenden oder wenn Sie einfache SQL-Anweisungen und -Verarbeitung verwenden, würde ich mich für die Wahl entscheiden, die Ihrer Meinung nach einfacher zu verfolgen ist. Im Allgemeinen bevorzuge ich NULL, damit das Ausführen von INSERT -Anweisungen nicht mühsam wird, wenn man vergisst, die leeren Felder auf NULL zu setzen.

4
Patrick

Nachdem ich mit Oracle arbeiten musste ( was Ihnen keine Unterscheidung erlaubt ), bin ich zu folgendem Schluss gekommen:

  • Aus logischer Sicht spielt es keine Rolle. Ich kann mir wirklich kein überzeugendes Beispiel vorstellen, bei dem die Unterscheidung zwischen NULL und Zeichenfolge mit der Länge Null einen Wert im DBMS hinzufügt.

  • Daraus folgt: Sie haben entweder eine NULLable-Spalte, die keine Null-Länge '' (Oracle-ish-Lösung) zulässt, oder eine NOT NULL - Spalte, die Null-Länge zulässt.

  • Und meiner Erfahrung nach macht '' viel mehr Sinn bei der Verarbeitung der Daten, da Sie normalerweise das Fehlen von a verarbeiten möchten Zeichenfolge als leere Zeichenfolge: Verkettung, Vergleich usw.

Hinweis: So kehren Sie zu meiner Oracle-Erfahrung zurück: Angenommen, Sie möchten eine Abfrage für eine Suchanforderung generieren. Wenn Sie '' Verwenden, können Sie einfach WHERE columnX = <searchvalue> Generieren und es funktioniert für Gleichheitssuchen. Wenn Sie NULL verwenden, müssen Sie WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL) ausführen. Bah! :-)

2
Martin

Sie unterscheiden sich auch aus gestalterischer Sicht:

z.B.

CREATE TABLE t (
    id INTEGER  NOT NULL,
    name CHARACTER(40),
    CONSTRAINT t_PK PRIMARY KEY (id)
);

CREATE UNIQUE INDEX t_AK1 ON t (name);

Sieht aus wie:

 \d t
          Table "public.t"
 Column |     Type      | Modifiers
--------+---------------+-----------
 id     | integer       | not null
 name   | character(40) |
Indexes:
    "t_pk" PRIMARY KEY, btree (id)
    "t_ak1" UNIQUE, btree (name)

Fügen wir einige Daten ein:

op=# insert into t(id, name ) values ( 1, 'Hello');
INSERT 0 1

op=# insert into t( id, name) values ( 2, '');
INSERT 0 1

op=# insert into t( id, name) values ( 3, '');

ERROR:  duplicate key value violates unique constraint "t_ak1"

Versuchen wir es jetzt mit null:

op=# insert into t( id, name) values (4, null );

INSERT 0 1

op=# insert into t( id, name) values (5, null);

INSERT 0 1

Dies ist erlaubt.

Soooooo: Nullen sind weder triviale Zeichenfolgen noch das Gegenteil.

Prost

2
Guy Birkbeck

Wenn wir über Theorie sprechen, dann sagen die Codd-Regeln, dass RDBMS NULL -Werte auf besondere Weise behandeln muss.

Wie genau dies verwendet wird, hängt von den Datenbankarchitekten ab, abhängig vom tatsächlichen Bereich Domäne - Aufgabe - Projekt - Anwendung - Bereich.

1
noonex