Ich weiß, dass dieses Thema ein bisschen umstritten ist und es gibt viele verschiedene Artikel / Meinungen im Internet. Leider gehen die meisten von ihnen davon aus, dass die Person nicht weiß, was der Unterschied zwischen NULL und einer leeren Zeichenfolge ist. So erzählen sie Geschichten über überraschende Ergebnisse mit Joins / Aggregaten und üben im Allgemeinen etwas fortgeschrittenere SQL-Lektionen. Auf diese Weise verpassen sie absolut den ganzen Punkt und sind daher für mich nutzlos. Hoffentlich werden diese Frage und alle Antworten das Thema etwas vorantreiben.
Nehmen wir an, ich habe eine Tabelle mit persönlichen Informationen (Name, Geburt usw.), in der eine der Spalten eine E-Mail-Adresse mit dem Typ varchar ist. Wir gehen davon aus, dass einige Personen aus irgendeinem Grund möglicherweise keine E-Mail-Adresse angeben möchten. Beim Einfügen solcher Daten (ohne E-Mail) in die Tabelle stehen zwei Optionen zur Verfügung: Setzen Sie die Zelle auf NULL oder setzen Sie sie auf eine leere Zeichenfolge (''). Nehmen wir an, ich kenne alle technischen Auswirkungen der Auswahl einer Lösung gegenüber einer anderen und kann für beide Szenarien korrekte SQL-Abfragen erstellen. Das Problem ist, dass beide Werte, auch wenn sie sich auf technischer Ebene unterscheiden, auf logischer Ebene genau gleich sind. Nachdem ich mir NULL angesehen hatte und zu dem Schluss gekommen bin, dass ich die E-Mail-Adresse des Mannes nicht kenne. Auch egal wie sehr ich es versucht habe, Ich konnte keine E-Mail mit NULL oder einer leeren Zeichenfolge senden, daher stimmen anscheinend die meisten SMTP-Server mit meiner Logik überein. Daher neige ich dazu, NULL zu verwenden, wenn ich den Wert nicht kenne und leere Zeichenfolgen für eine schlechte Sache halte.
Nach einigen intensiven Diskussionen mit Kollegen kam ich mit zwei Fragen:
Bin ich zu Recht davon ausgegangen, dass die Verwendung einer leeren Zeichenfolge für einen unbekannten Wert dazu führt, dass eine Datenbank über die Fakten "lügt"? Genauer gesagt: Wenn ich die Vorstellung von SQL von dem, was Wert ist und was nicht, verwende, könnte ich zu dem Schluss kommen: Wir haben eine E-Mail-Adresse, nur indem wir herausfinden, dass sie nicht null ist. Aber wenn ich später versuche, eine E-Mail zu senden, komme ich zu einem widersprüchlichen Ergebnis: Nein, wir haben keine E-Mail-Adresse, die @! # $ Database muss gelogen haben!
Gibt es ein logisches Szenario, in dem ein leerer String '' ein so guter Träger für wichtige Informationen sein könnte (neben Wert und ohne Wert), dass das Speichern auf andere Weise mühsam / ineffizient wäre (wie bei einer zusätzlichen Spalte). Ich habe viele Posts gesehen, in denen behauptet wurde, dass es manchmal gut ist, leere Zeichenfolgen zusammen mit realen Werten und NULL-Werten zu verwenden, aber bisher kein logisches Szenario (in Bezug auf das SQL / DB-Design) gesehen zu haben.
PS Manche Leute werden versucht sein zu antworten, dass es nur eine Frage des persönlichen Geschmacks ist. Ich stimme nicht zu. Für mich ist es eine Designentscheidung mit wichtigen Konsequenzen. Daher würde ich gerne Antworten sehen, bei denen die Meinung dazu aus logischen und / oder technischen Gründen gestützt wird.
''
auch in Oracle nicht das gleiche wieNULL
. Wenn Sie beispielsweise eineCHAR(1)
Spalte zuweisen , die der Wert''
ergibt' '
(dh ein Leerzeichen), nichtNULL
. Außerdem, wenn Jacek Oracle verwendet, würde diese Frage wahrscheinlich nicht einmal auftauchen :-)'' IS NULL
sietrue
in PL / SQL ausgewertet wird .Antworten:
Ich würde sagen, das
NULL
ist die richtige Wahl für "keine E-Mail-Adresse". Es gibt viele "ungültige" E-Mail-Adressen und "" (leere Zeichenfolge) ist nur eine. Zum Beispiel ist "foo" keine gültige E-Mail-Adresse, "a @ b @ c" ist nicht gültig und so weiter. Nur weil "" keine gültige E-Mail-Adresse ist, ist dies kein Grund, sie als Wert für "keine E-Mail-Adresse" zu verwenden.Ich glaube, Sie haben Recht, wenn Sie sagen, dass "" nicht der richtige Weg ist, um "Ich habe keinen Wert für diese Spalte" zu sagen. "" ist ein Wert.
Ein Beispiel, bei dem "" ein gültiger Wert sein kann, wobei "" der zweite
NULL
Vorname einer Person sein kann. Da nicht jeder einen zweiten Vornamen hat, müssen Sie zwischen "kein zweiter Vorname" ("" - leere Zeichenfolge) und "Ich weiß nicht, ob diese Person einen zweiten Vornamen hat oder nicht" (NULL
) unterscheiden. Es gibt wahrscheinlich viele andere Beispiele, in denen eine leere Zeichenfolge immer noch ein gültiger Wert für eine Spalte ist.quelle
NULL
bedeutet nicht, dass es keine E-Mail-Adresse gibt. Ich denke, es bedeutet, dass die E-Mail-Adresse derzeit nicht bekannt ist, nicht bekannt ist oder aus anderen Gründen nicht ausgefüllt werden kann. Glücklicherweise gibt es wahrscheinlich keine Situation, in der man die Informationen über Personen, die wirklich keine E-Mail-Adresse haben und nicht haben möchten, in einer Datenbank speichern möchte, da sonst wahrscheinlich ein separates boolesches Feld erforderlich wäre.Ich stimme den obigen Kommentaren zu, füge aber dieses Argument als Hauptmotivation hinzu:
Verwenden Sie zur Selbstdokumentation der intuitiven Codierung NULL anstelle von leeren Zeichenfolgen.
quelle
In Ihrem Beispiel würde ich eine leere Zeichenfolge verwenden, wenn der Wert direkt aus dem Webfeld stammt. Wenn der Benutzer angeben kann, dass er keine E-Mails bereitstellen oder löschen möchte, dann NULL.
Hier sind Links zu Punkten, die Sie in Betracht ziehen könnten: https://stackoverflow.com/questions/405909/null-vs-empty-when-deal-with-user-input/405945#405945
--- bearbeitet (Antwort auf Thomas Kommentar) ---
Datenbanken leben nicht ohne Anwendungen, die sie verwenden. Die Definition von NULL oder '' hat keinen Wert, wenn die Anwendung sie nicht richtig verwenden kann.
Stellen Sie sich ein Beispiel vor, in dem der Benutzer das LANGE Formular ausfüllt und die Eingabetaste drückt, um eine permanente Anforderung an den Server zu senden. Er könnte gerade dabei sein, seine E-Mail-Adresse einzugeben. Höchstwahrscheinlich möchten Sie alles, was er hat, im E-Mail-Feld speichern, damit er es später fertigstellen kann. Was ist, wenn er nur ein Zeichen eingegeben hat? Was ist, wenn er ein Zeichen eingibt und es dann löscht? Wenn E-Mails nicht benötigt werden, möchten Benutzer sie manchmal löschen. Dies ist der einfachste Weg, um ein Feld zu löschen. Auch für den Fall, dass eine E-Mail nicht benötigt wird, lohnt es sich, diese vor dem Senden zu validieren.
Ein weiteres Beispiel: Benutzer geben eine E-Mail als spamto @ [bigcompany] .com an. In diesem Fall muss keine E-Mail gesendet werden, obwohl sie vorhanden und gültig ist (und möglicherweise sogar vorhanden ist). Das Senden einer solchen E-Mail ist vielleicht billig, aber wenn es 10.000 Benutzer mit solchen E-Mails für tägliche Abonnements gibt, kann eine solche Validierung viel Zeit sparen.
quelle
Ich denke, Dean Hardings Antwort deckt dies wirklich gut ab. Vor diesem Hintergrund möchte ich erwähnen, dass Sie, wenn Sie auf DB-Ebene über NULLs und leere Strings sprechen, über Ihre anderen Datentypen nachdenken sollten. Würden Sie ein Mindestdatum speichern, wenn kein Datum angegeben ist? oder -1, wenn kein int angegeben wird? Wenn Sie einen Wert speichern, für den Sie keinen Wert haben, müssen Sie eine ganze Reihe von Nicht-Werten nachverfolgen. Mindestens einer für jeden Datentyp (möglicherweise mehr, wenn Sie Fälle erhalten, in denen -1 ein tatsächlicher Wert ist, sodass Sie eine Alternative usw. benötigen). Wenn Sie etwas "Fudgy" auf Anwendungsebene tun müssen / möchten, ist dies eine Sache, aber Sie müssen Ihre Daten nicht verunreinigen.
quelle
Leider hat Oracle die Darstellung des VARCHAR-Strings der Länge Null mit der Darstellung von NULL verwechselt. Sie werden beide intern durch ein einzelnes Byte mit dem Wert Null dargestellt. Dies erschwert die Diskussion um einiges.
Ein Großteil der Verwirrung um NULL dreht sich um dreiwertige Logik . Betrachten Sie den folgenden Pseudocode:
Sie würden die dritte Nachricht nicht erwarten, aber das ist, was Sie unter drei bewerteten Logik erhalten würden. Die drei-wertige Logik führt die Menschen zu zahlreichen Fehlern.
Eine andere Quelle der Verwirrung ist das Ziehen von Schlussfolgerungen aus dem Fehlen von Daten, wie das Ziehen einer Schlussfolgerung aus dem Hund, der in der Nacht nicht gebellt hat. Oft waren diese Schlussfolgerungen nicht das, was der Verfasser der NULL zu übermitteln beabsichtigte.
Trotzdem gibt es viele Situationen, in denen NULL mit dem Fehlen von Daten zurechtkommt und genau die gewünschten Ergebnisse erzielt. Ein Beispiel sind Fremdschlüssel in optionalen Beziehungen. Wenn Sie NULL verwenden, um keine Beziehung in einer bestimmten Zeile anzugeben, wird diese Zeile aus einer inneren Verknüpfung entfernt, genau wie Sie es erwarten würden.
Beachten Sie auch, dass Sie mit NULL auch dann fertig werden müssen, wenn Sie NULL in den gespeicherten Daten (sechste Normalform) vollständig vermeiden, wenn Sie äußere Verknüpfungen ausführen.
quelle
Verwenden Sie Null.
Es hat keinen Sinn, den Wert '' zu speichern, wenn Sie das Feld in der Tabelle einfach auf null setzen möchten. Es macht auch Fragen offensichtlicher.
Welche SQL-Abfrage ist offensichtlicher und lesbarer, wenn Sie Benutzer mit einer E-Mail-Adresse suchen möchten?
SELECT * FROM Users WHERE email_address != ''
SELECT * FROM Users WHERE email_address IS NOT NULL
SELECT * FROM Users WHERE email_address != '' and email_address IS NOT NULL
Ich würde sagen, 2 ist. Obwohl 3 robuster ist, wenn schlechte Daten gespeichert sind.
Für den Fall, dass die E-Mail-Adresse auf dem Formular optional ist, sollte sie auch in der Tabelle enthalten sein. In SQL ist es ein nullwertfähiges Feld, was bedeutet, dass es nicht bekannt ist.
Ich kann mir keinen vernünftigen Geschäftswert vorstellen, wenn ich eine leere Zeichenfolge in einer anderen Tabelle als nur schlechtes Design speichere. Es ist so, als würde man einen String-Wert von 'NULL' oder 'BLANK' speichern und die Entwickler davon ausgehen, dass er null oder ein leerer String ist. Für mich ist das schlechtes Design. Warum das speichern, wenn es NULL gibt?
Verwenden Sie einfach NULL, und Sie werden alle ein bisschen glücklicher machen.
MEHR INFO:
SQL verwendet ein dreiwertiges Logiksystem: True, False und Unknown.
Für eine bessere und detailliertere Erklärung empfehle ich Entwicklern Folgendes: SQL-Abfragen - jenseits von WAHR und FALSCH .
quelle
Bei der spezifischen technischen Frage ist das Problem nicht null im Vergleich zu einer leeren Zeichenfolge, sondern ein Validierungsfehler . Eine leere Zeichenfolge ist keine gültige E-Mail-Adresse!
Für die philosophische Frage ist die Antwort ähnlich: Validieren Sie Ihre Eingaben. Wenn eine leere Zeichenfolge ein gültiger Wert für das betreffende Feld ist, erwarten Sie ihn und codieren Sie ihn. Wenn nicht, verwenden Sie null.
Eine leere Zeichenfolge wäre eine gültige Eingabe, um die Frage zu beantworten: Was hat der Pantomime der Giraffe gesagt?
quelle
Ich könnte mir einen Grund für NULL und die leere Zeichenkette vorstellen:
[email protected]
NULL
Empty String.
Ich würde das jedoch nicht empfehlen und ein separates Feld verwenden, um zu fragen, ob Sie wissen, dass keines vorhanden ist.
quelle
Die Frage, wie ich es verstehe, ist, welche Interpretationen von NULL und leerer Zeichenkette gewählt werden sollten. Dies hängt davon ab, in wie vielen Zuständen sich das jeweilige Feld befinden kann.
Die Interpretation hängt davon ab, wie auf die Datenbank zugegriffen wird. Wenn der Code eine Ebene enthält, die die Datenbank vollständig abstrahiert, ist die Auswahl einer funktionsfähigen Richtlinie (einschließlich Two-Coulmn) völlig akzeptabel. (Es ist jedoch wichtig, die Richtlinie klar zu dokumentieren.) Wenn jedoch an mehreren Stellen auf die Datenbank zugegriffen wird, sollten Sie ein sehr einfaches Schema verwenden, da der Code schwerer zu warten ist und in diesem Fall möglicherweise fehlerhaft ist.
quelle
Grundsätzlich gibt es auf logischer Ebene keinen Unterschied zwischen "ungültigem" Wert und "keine Benutzereingabe", sondern meistens nur "Sonderfälle". Fehlerfall.
NULL zu haben, nimmt zusätzlichen Platz in Anspruch: ceil (columns_with_null / 8) in Bytes / pro Zeile.
Leere Zelle und Null sind beide Möglichkeiten, um zu markieren, dass etwas nicht stimmt. Warum brauchst du 2 "falsche" Zustände? Warum NULL-Werte verwenden, wenn sie zusätzlichen Speicherplatz beanspruchen und genau das Gleiche bedeuten wie leere Zeichenfolgen? Das führt nur zu Verwirrung und Redundanz, wenn Sie zwei Bedeutungen haben (die genau dasselbe bedeuten könnten). Es ist leicht zu vergessen, dass Sie NULL anstelle von leeren Zeichenfolgen verwenden sollten (wenn der Benutzer beispielsweise einige Felder weggelassen hat).
Und Ihre Daten können zu einem Durcheinander werden. In einer perfekten Welt würde man sagen "die Daten werden immer korrekt sein und ich werde mich erinnern" ... aber wenn Leute in einem Team arbeiten müssen und nicht jeder genau auf Ihrem Niveau ist, ist es nicht ungewöhnlich zu sehen, WO (aa. xx <> '' AND bb.zz IST NICHT NULL)
Anstatt meine Teammitglieder jeden zweiten Tag zu korrigieren, erzwinge ich einfach eine einfache Regel. Keine Nullwerte, NIE!
Das Zählen von NON-NULL-Werten ist schneller ... die einfache Frage ist, wofür müssten Sie das tun?
quelle
VARCHAR
Spalte mindestens 1 Byte benötigt, um die Länge der Zeichenfolge zu speichern, auch wenn sie Null ist.Ich neige dazu, es nicht aus der DB-Perspektive, sondern aus einer Programmperspektive zu betrachten. Ich weiß, dass diese Frage für den SQL-Klick ist, aber wirklich, wie viele Benutzer greifen nicht mehr direkt auf Daten zu?
In einem Programm mag ich nicht null / nothing. Es gibt ein paar Ausnahmen, aber genau das sind sie. Und diese Ausnahmen sind wirklich nur schlechte Implementierungen.
Wenn der Benutzer die E-Mail also nicht eingegeben hat, sollte es etwas geben, das bestimmt, ob dies gültig ist oder nicht. Wenn eine leere E-Mail in Ordnung ist, wird eine leere Zeichenfolge angezeigt. Wenn der Benutzer keine E-Mail eingegeben hat und dies gegen eine Regel verstößt, sollte das Objekt dies anzeigen.
Die Idee, dass Null Sinn hat, ist eine alte Schule und muss von modernen Programmierern umgangen werden.
Warum kann das E-Mail-Feld auch im DB-Design keine Nullen zulassen und keine Zeichenfolge mit einer Länge von Null haben und ein anderes Feld, das angibt, ob der Benutzer etwas eingegeben hat? Ist ein bisschen so viel von einem DBMS zu verlangen? Die DB sollte meiner Meinung nach weder die Geschäftslogik noch die Anzeigelogik behandeln. Es wurde nicht dafür gebaut und erledigt daher einen sehr schlechten Job damit.
quelle
Ich denke nicht, dass es wichtig ist, aber ich mag es besser, wenn der NULL da ist.
Wenn ich die in einer Tabelle angezeigten Daten ansehe (wie in SQL Server Management Studio), kann ich einen fehlenden Wert besser unterscheiden, wenn NULL angegeben ist und der Hintergrund eine andere Farbe hat.
Wenn ich ein Leerzeichen sehe, frage ich mich immer, ob es wirklich leer ist oder ob es ein Leerzeichen oder unsichtbare Zeichen gibt. Mit NULL ist es auf den ersten Blick garantiert leer.
Normalerweise unterscheide ich die Werte in der Anwendung nicht, weil es unerwartet und seltsam ist, dass NULL und leere Zeichenfolge etwas anderes bedeuten würden. Und die meiste Zeit gehe ich defensiv vor und beschäftige mich nur mit beiden Staaten. Aber für mich als Mensch ist NULL beim Betrachten der Daten einfacher zu verarbeiten.
quelle