Standardmäßige Verwendung von 'Z' anstelle von NULL zur Darstellung fehlender Daten?

76

Außerhalb des Arguments, ob NULLs jemals verwendet werden sollten oder nicht: Ich bin für eine vorhandene Datenbank verantwortlich, die NULL verwendet, um "fehlende oder nie eingegebene" Daten zu bedeuten. Es unterscheidet sich von einer leeren Zeichenfolge, was bedeutet, dass "ein Benutzer diesen Wert festgelegt und" leer "ausgewählt hat."

Ein anderer Auftragnehmer des Projekts ist fest davon überzeugt, dass NULLs für mich nicht existieren; ich verwende niemals NULL und niemand anderes sollte es auch nicht. Was mich jedoch verwirrt, ist, dass das Team des Auftragnehmers, da es den Unterschied zwischen "fehlend / nie eingegeben" und "absichtlich leer oder vom Benutzer als unbekannt angegeben" anerkennt, ein einziges Zeichen "Z" in seinem Code und in gespeicherten Prozeduren verwendet stellen "fehlend / nie eingegeben" mit der gleichen Bedeutung wie NULL im Rest der Datenbank dar.

Obwohl unser gemeinsamer Kunde eine Änderung beantragt hat und ich diese Anfrage unterstützt habe, nennt das Team dies als "Standardpraxis" unter DBAs, die weit fortgeschrittener sind als ich. Sie zögern, NULLs nur aufgrund meiner unwissenden Anfrage zu verwenden. Kann mir jemand helfen, meine Unwissenheit zu überwinden? Gibt es einen Standard oder eine kleine Gruppe von Personen oder sogar eine einzige laute Stimme unter SQL-Experten, die die Verwendung von 'Z' anstelle von NULL befürwortet?

Aktualisieren

Ich habe eine Antwort vom Auftragnehmer hinzuzufügen. Folgendes sagte er, als der Kunde darum bat, die speziellen Werte zu entfernen, um NULL in Spalten ohne Daten zuzulassen:

Grundsätzlich habe ich die Datenbank so konzipiert, dass NULL-Werte nach Möglichkeit vermieden werden. Hier ist die Begründung:

Ein NULL-Wert in einem String-Feld [VARCHAR] ist niemals erforderlich, da ein leerer String (Länge Null) genau dieselben Informationen liefert.

Ein NULL-Wert in einem ganzzahligen Feld (z. B. ein ID-Wert) kann mithilfe eines Werts behandelt werden, der in den Daten niemals vorkommen würde (z. B. -1 für ein ganzzahliges IDENTITY-Feld).

Ein NULL in einem Datumsfeld kann leicht zu Komplikationen bei der Datumsberechnung führen. In einer Logik, die Datumsunterschiede berechnet, z. B. die Differenz in Tagen zwischen einem [Wiederherstellungsdatum] und einem [OnsetDate], wird die Logik beispielsweise gesprengt, wenn eines oder beide Daten NULL sind - es sei denn, beide Daten werden explizit berücksichtigt NULL sein. Das ist zusätzliche Arbeit und zusätzliche Handhabung. Wenn für [RecoveryDate] und [OnsetDate] "Standard-" oder "Platzhalter" -Daten verwendet werden (z. B. "01.01.1900"), zeigen mathematische Berechnungen möglicherweise "ungewöhnliche" Werte an - die Datumslogik wird jedoch nicht angezeigt.

NULL-Handling ist traditionell ein Bereich, in dem Entwickler Fehler in gespeicherten Prozeduren machen.

In meinen 15 Jahren als DBA habe ich es am besten gefunden, NULL-Werte nach Möglichkeit zu vermeiden.

Dies scheint die meist negative Reaktion auf diese Frage zu bestätigen. Anstatt einen akzeptierten 6NF-Ansatz zum Entwerfen von NULL-Werten anzuwenden, werden spezielle Werte verwendet, um "NULL-Werte nach Möglichkeit zu vermeiden". Ich habe diese Frage offen gestellt und bin froh, dass ich mehr über die Debatte "NULLs sind nützlich / NULLs sind böse" erfahren habe, aber ich bin jetzt ziemlich zufrieden damit, den Ansatz der "besonderen Werte" als völligen Unsinn zu bezeichnen.

Eine leere Zeichenfolge (Länge Null) liefert genau die gleichen Informationen.

Nein, das tut es nicht. In der vorhandenen Datenbank, die wir ändern, bedeutet NULL "nie eingegeben" und leere Zeichenfolge "als leer eingegeben".

NULL-Handling ist traditionell ein Bereich, in dem Entwickler Fehler in gespeicherten Prozeduren machen.

Ja, aber diese Fehler wurden tausende Male von Tausenden von Entwicklern gemacht, und die Lehren und Vorbehalte zur Vermeidung dieser Fehler sind bekannt und dokumentiert. Wie hier erwähnt: Unabhängig davon, ob Sie NULL-Werte akzeptieren oder ablehnen, ist die Darstellung fehlender Werte ein gelöstes Problem . Es ist nicht erforderlich, eine neue Lösung zu erfinden, nur weil Entwickler weiterhin leicht zu überwindende (und leicht zu identifizierende) Fehler machen.


Als Fußnote: Ich bin seit mehr als 20 Jahren DBE und Entwickler (was sicherlich genug Zeit ist, um den Unterschied zwischen einem Datenbankingenieur und einem Datenbankadministrator zu erkennen). Während meiner Karriere war ich immer im Camp "NULLs sind nützlich", obwohl mir bewusst war, dass einige sehr kluge Leute anderer Meinung waren. Ich war äußerst skeptisch gegenüber dem Ansatz der "besonderen Werte", aber nicht gut genug mit den Wissenschaftlern von "Wie man NULL auf die richtige Weise vermeidet" vertraut, um einen festen Standpunkt zu vertreten. Ich liebe es immer, neue Dinge zu lernen - und ich habe nach 20 Jahren noch viel zu lernen. Vielen Dank an alle, die dazu beigetragen haben, dass dies eine nützliche Diskussion wurde.

Boris Nikolaevich
quelle
60
NULL existiert, um eine trinäre Logik zu ermöglichen, die notwendig ist, um die referenzielle Integrität zu bewahren, wenn keine vollständigen Informationen vorliegen. Ich würde jeden proklamierten DB-Experten, der entschieden gegen sie ist, als vollständige und vollständige BS bezeichnen!
Gordon
17
Ich habe noch nie von dieser Praxis gehört.
Calvin Allen
14
Hat der Auftragnehmer auch für numerische Daten einen Ersatz-NULL vorgeschlagen?
Andriy M
14
@Andriy: Das ist einfach zu lösen, alle Experten speichern Zahlen in Zeichenfeldern und wirken (mit Z-Checks!) Nach Bedarf. Oh warte, ich bin auf der falschen Seite .
Mu ist zu kurz
12
Ich vermute, dass dieser Auftragnehmer einmal versucht hat, etwas auszuführen, WHERE Column = NULLund war verwirrt darüber, warum er keine Ergebnisse erzielt hat.
Mike Caron

Antworten:

104

Entlassen Sie Ihren Auftragnehmer.

Okay, im Ernst, das ist keine Standardpraxis. Dies kann einfach gesehen werden, weil alle RDBMS, mit denen ich jemals gearbeitet habe, NULL implementieren, Logik für NULL, NULL in Fremdschlüsseln berücksichtigen, ein anderes Verhalten für NULL in COUNT usw. haben usw.

Ich würde tatsächlich behaupten, dass die Verwendung von 'Z' oder einem anderen Platzhalter schlechter ist. Sie benötigen weiterhin Code, um nach 'Z' zu suchen. Sie müssen aber auch dokumentieren, dass 'Z' nicht 'Z' bedeutet, sondern etwas anderes. Und Sie müssen sicherstellen, dass diese Dokumentation gelesen wird. Und was passiert dann, wenn 'Z' jemals zu einem gültigen Datenelement wird? (Wie ein Feld für eine Initiale?)

Grundsätzlich würde ich auch ohne Erörterung der Gültigkeit von NULL gegen 'Z' darauf bestehen, dass der Auftragnehmer den in Ihrem Unternehmen geltenden Standardpraktiken entspricht, nicht seinen. Die Einführung seiner Standardpraxis in einer Umgebung mit einer alternativen Standardpraxis führt zu Verwirrung, Wartungsaufwand, Missverständnissen und letztendlich zu erhöhten Kosten und Fehlern.


BEARBEITEN

Es gibt Fälle, in denen meiner Meinung nach die Verwendung einer Alternative zu NULL gültig ist. Aber nur dort, wo dies den Code reduziert, anstatt Sonderfälle zu erstellen, die berücksichtigt werden müssen.

Ich habe das zum Beispiel für datumsgebundene Daten verwendet. Wenn Daten zwischen einem Start- und einem Enddatum gültig sind, kann der Code vereinfacht werden, indem keine NULL-Werte vorhanden sind. Stattdessen könnte ein NULL-Startdatum durch '01 Jan 1900 'und ein NULL-Enddatum durch '31 Dec 2079' ersetzt werden.

Dies kann das Verhalten immer noch von dem ändern, was zu erwarten ist, und sollte daher mit Vorsicht angewendet werden:

  • WHERE end-date IS NULL Geben Sie keine Daten mehr an, die noch gültig sind
  • Sie haben gerade Ihren eigenen Millennium-Bug erstellt
  • usw.

Dies entspricht der Reformierung von Abstraktionen, sodass alle Eigenschaften immer gültige Werte haben können. Es unterscheidet sich deutlich von der impliziten Codierung einer bestimmten Bedeutung in willkürlich ausgewählte Werte.

Entlassen Sie trotzdem den Auftragnehmer.

MatBailie
quelle
21
+1 von mir; genau richtig: "Ich würde tatsächlich behaupten, dass die Verwendung von 'Z' oder eines anderen Platzhalters schlechter ist. Sie benötigen immer noch Code, um nach 'Z' zu suchen. Sie müssen jedoch auch dokumentieren, dass 'Z' nicht 'Z' bedeutet. es bedeutet etwas anderes. "
Mitch Wheat
20
Was wir brauchen, ist ein spezieller Wert - nicht NULL, da NULL böse ist - um fehlende Daten darzustellen. Etwas, das sich von allen anderen Werten unterscheidet, vielleicht sogar von sich selbst (da zwei Unbekannte nicht einfach deshalb gleichgesetzt werden können, weil sie unbekannt sind). Einige Spalten würden mit diesem Wert offensichtlich keinen Sinn ergeben, daher sollte dies verboten werden. Um die Sache zu vereinfachen, benötigen wir spezielle Operatoren wie IS UNKNOWN oder IS NOT UNKNOWN.
Mike Caron
5
Bauunternehmer haben oft gute Ratschläge aus tiefer Erfahrung, aber nur weil dies manchmal passiert, heißt das nicht, dass Sie den Schafen über die empfohlene gefährliche Klippe folgen müssen. Informieren Sie sie darüber, dass Sie der Master und Eigentümer der Datenbank sind: Die Entwicklung erfolgt wie angegeben: einhalten oder sterben.
Wallyk
2
Wenn ein Benutzer Z eingibt, speichern Sie offensichtlich ZZ. Wenn sie ZZ eingeben, speichern Sie ZZZ und so weiter. Dies erfordert, dass Sie alle Ihre Spalten um ein Zeichen vergrößern, aber das sollte kein Problem sein.
Chas. Owens
2
+1 von mir im Allgemeinen - aber besonders für die Bearbeitung, bei der es sinnvoll sein kann, Zaunpfostenwerte für Datumsbereiche (Mindestdatum / Höchstdatum) zu verwenden, da so viel Code gespeichert werden kann - insbesondere, wenn Sie vergleichen / überprüfen müssen für Überlappungen in Datumsbereichen. In diesen Fällen bedeutet Min-Datum "seit immer" und Max-Datum "bis für immer", was sich von NULL unterscheidet und "nicht sicher" oder "egal" bedeutet.
Joel Brown
26

Dies ist leicht eine der seltsamsten Meinungen, die ich je gehört habe. Die Verwendung eines magischen Werts zur Darstellung von "keine Daten" anstelle von NULL bedeutet, dass jeder Code, den Sie haben, die Ergebnisse nachbearbeiten muss, um die Werte "keine Daten" / "Z" zu berücksichtigen / zu verwerfen.

NULL ist etwas Besonderes, da die Datenbank es in Abfragen verarbeitet. Nehmen Sie zum Beispiel diese zwei einfachen Abfragen:

select * from mytable where name = 'bob';
select * from mytable where name != 'bob';

Wenn namees jemals NULL ist, wird es offensichtlich nicht in den Ergebnissen der ersten Abfrage angezeigt. Noch wichtiger ist, dass es auch nicht in den Ergebnissen der zweiten Abfrage angezeigt wird. NULL entspricht nichts anderem als einer expliziten Suche nach NULL, wie in:

select * from mytable where name is NULL;

Und was passiert, wenn die Daten Z als gültigen Wert haben könnten? Angenommen, Sie speichern die mittlere Initiale von jemandem? Würde Zachary Z Zonkas mit Leuten ohne mittlere Initiale in Kontakt kommen? Oder würde sich Ihr Auftragnehmer einen weiteren magischen Wert einfallen lassen, um damit umzugehen?

Vermeiden Sie magische Werte, bei denen Sie Datenbankfunktionen in Code implementieren müssen, den die Datenbank bereits vollständig verarbeiten kann. Dies ist ein gelöstes und gut verstandenes Problem, und es kann sein, dass Ihr Auftragnehmer den Begriff NULL nie wirklich missbilligt hat und es daher vermeidet, ihn zu verwenden.

unpythonisch
quelle
22

Wenn die Domäne fehlende Werte zulässt, ist die Verwendung von NULL zur Darstellung von "undefiniert" vollkommen in Ordnung (dafür ist sie da). Der einzige Nachteil ist, dass der Code, der die Daten verbraucht, geschrieben werden muss, um nach NULL-Werten zu suchen. So habe ich es immer gemacht.

Ich habe noch nie von der Verwendung von 'Z' zur Darstellung fehlender Daten gehört (oder in der Praxis gesehen). Kann "der Auftragnehmer dies als" Standardpraxis "unter den Datenbankadministratoren anführen" einige Beweise für diese Behauptung liefern? Wie bei @Dems erwähnt, müssen Sie auch dokumentieren, dass 'Z' nicht 'Z' bedeutet: Was ist mit einer MiddleInitialSpalte?

Wie Aaron Alton und viele andere glaube ich, dass NULL-Werte ein wesentlicher Bestandteil des Datenbankdesigns sind und gegebenenfalls verwendet werden sollten.

Mitch Wheat
quelle
3
Ich denke, der Schlüssel hier ist "Wenn die Domain fehlende Werte zulässt ..." Es scheint mir, dass es eine Zeit und einen Ort gibt, um die Verwendung von NULL-Werten zu unterstützen, und eine Zeit und einen Ort, um sie zu vermeiden, und es braucht etwas Weisheit den Unterschied kennen. Ich habe manchmal das Gefühl, dass, wenn ein Junior-DBE / DBA eine Einschränkung wie "NULL-Werte können zu unerwarteten Ergebnissen bei Abfragen und Berechnungen führen, wenn Sie deren Verhalten nicht berücksichtigen", seine Knie-Ruck-Reaktion darin besteht, die gesamte NULL-Verwendung zu kennzeichnen so schlecht wie. Sobald es zu einer religiös vertretenen Meinung wird, bleibt es für den Rest seiner Karriere bei ihm.
Boris Nikolaevich
1
Das Vergessen der WHERE-Klausel in einem DELETE oder UPDATE kann Ihrer Datenbank Schaden zufügen => Verwenden Sie sie niemals. Entweder machen Sie die Daten gleich beim ersten Mal richtig oder öffnen Sie die Tabelle in einem Editor und machen Sie es selbst.
MatBailie
Beachten Sie außerdem, dass OUTER-Joins NULL-Werte ergeben und daher nicht verwendet werden sollten. Das Gleiche gilt für ROLL UP.
MatBailie
3
Z wird in einigen Standards verwendet, um eine GMT-Zeitzone darzustellen.
Erick Robertson
2
@Erick, das ist ein weiterer Grund, Z nicht zu verwenden, um "kein Wert" zu bedeuten.
Boris Nikolaevich
17

Selbst wenn Sie es irgendwie schaffen, all Ihren gegenwärtigen und zukünftigen Entwicklern und Datenbankadministratoren "Z" anstelle von NULL zu erklären, und selbst wenn sie alles perfekt codieren, werden Sie den Optimierer immer noch verwirren, da er nicht weiß, dass Sie dies erfunden haben .

Die Verwendung eines speziellen Werts zur Darstellung von NULL (der bereits ein spezieller Wert zur Darstellung von NULL ist) führt zu Abweichungen in den Daten. zB Am 1. Januar 1900 sind so viele Dinge passiert, dass der Optimierer nicht mehr in der Lage ist, den tatsächlichen Zeitraum zu verstehen, der für Ihre Anwendung wirklich relevant ist.

Dies ist wie die Entscheidung eines Managers: "Das Tragen einer Krawatte ist schlecht für die Produktivität, daher werden wir alle Klebeband um den Hals tragen. Problem gelöst."

WW.
quelle
10
+1 nur für den Satz "Verwenden eines speziellen Werts zur Darstellung von NULL (der bereits ein spezieller Wert zur Darstellung von NULL ist)". . .
Mike Sherrill 'Cat Recall'
Ich dachte, dass eine Fliege genau das war, eine Krawatte, die durch Klebeband ersetzt wurde, das für den Anlass besser geeignet war ...
Soren
9

Ich habe noch nie von der weit verbreiteten Verwendung 'Z'als Ersatz für gehört NULL.

(Übrigens würde ich nicht besonders gerne mit einem Auftragnehmer zusammenarbeiten, der Ihnen ins Gesicht sagt, dass sie und andere "fortgeschrittene" Datenbankadministratoren so viel besser informiert und besser sind als Sie.)

 +=================================+
 |  FavoriteLetters                |
 +=================================+
 |  Person      |  FavoriteLetter  |
 +--------------+------------------+
 |  'Anna'      |  'A'             |
 |  'Bob'       |  'B'             |
 |  'Claire'    |  'C'             |
 |  'Zaphod'    |  'Z'             |
 +---------------------------------+

Wie würde Ihr Auftragnehmer die Daten aus der letzten Zeile interpretieren?

Wahrscheinlich würde er einen anderen "magischen Wert" in dieser Tabelle wählen, um eine Kollision mit den realen Daten zu vermeiden 'Z'? Das heißt, Sie müssen sich mehrere magische Werte merken und auch, welcher wo verwendet wird. Wie ist das besser, als nur einen magischen Token zu NULLhaben und sich an die dreiwertigen Logikregeln (und Fallstricke) zu erinnern, die damit einhergehen? NULList zumindest im Gegensatz zu Ihrem Auftragnehmer standardisiert 'Z'.

Ich mag es auch nicht besonders NULL, aber es sinnlos überall durch einen tatsächlichen Wert (oder schlimmer durch mehrere tatsächliche Werte) zu ersetzen, ist fast definitiv schlechter als NULL.

Lassen Sie mich meinen obigen Kommentar hier wiederholen, um die Sichtbarkeit zu verbessern: Wenn Sie etwas Ernstes lesen möchten, das von Leuten, die dagegen sind NULL, begründet ist, würde ich den kurzen Artikel "Wie man mit fehlenden Informationen umgeht, ohne NULL-Werte zu verwenden" (Links zu einem PDF von) empfehlen Die Homepage des dritten Manifests ).

stakx - nicht mehr beitragen
quelle
4

Für das korrekte Datenbankdesign sind im Prinzip keine Nullen erforderlich. Tatsächlich gibt es viele Datenbanken, die ohne Verwendung von Null entworfen wurden, und es gibt viele sehr gute Datenbankdesigner und ganze Entwicklungsteams, die Datenbanken ohne Verwendung von Null entwerfen. Im Allgemeinen ist es gut, beim Hinzufügen von Nullen zu einer Datenbank vorsichtig zu sein, da diese später zwangsläufig zu falschen oder mehrdeutigen Ergebnissen führen.

Ich habe noch nicht davon gehört, dass Z als "Standardpraxis" als Platzhalterwert anstelle von Nullen verwendet wird, aber ich gehe davon aus, dass Ihr Auftragnehmer sich auf das Konzept der Sentinel-Werte im Allgemeinen bezieht , die manchmal im Datenbankdesign verwendet werden. Eine viel üblichere und flexiblere Möglichkeit, Nullen zu vermeiden, ohne "Dummy" -Daten zu verwenden, besteht darin, sie einfach zu entwerfen. Zerlegen Sie die Tabelle so, dass jeder Faktentyp in einer Tabelle aufgezeichnet wird, die keine "zusätzlichen", nicht angegebenen Attribute enthält.

nvogel
quelle
1
Ich denke, der Auftragnehmer bedeutet wörtlich, "Z" für "Weiß nicht" zu verwenden.
Wallyk
Leider ist @wallyk grundsätzlich richtig: Dies ist keine akademische oder theoretische Diskussion; Da ich selbst Entwickler bin, habe ich den Code und die gespeicherten Prozeduren durchlaufen. Der Auftragnehmer verwendet das Literalzeichen 'Z' für fehlende / nicht eingegebene Werte. (Werte, die tatsächlich "unbekannt, aber beantwortet" sind, sind selbst im aktuellen Datenbankdesign niemals NULL. Beide verwenden eine leere Zeichenfolge für Textfelder oder das Zeichen "U" für Dropdown-Listen, um anzuzeigen, dass der Benutzer die Frage beantwortet hat und die Antwort war "Ich weiß nicht.")
Boris Nikolaevich
@dportas - Ich erkenne, dass für ein korrektes Datenbankdesign keine Nullen erforderlich sind, aber da ich mich in "Es gibt eine Zeit und einen Ort, an dem NULL verwendet werden kann, wenn Sie wissen, wie man das richtig macht", dem Hauptzweck des Die Frage war zu verstehen, ob die Verwendung von 'Z' in einem guten Datenbankdesign durch jemanden aus dem "NoNULL" -Lager entweder Standard, allgemein oder von irgendjemandem gefördert wurde.
Boris Nikolaevich
3

Als Antwort auf die Kommentare des Auftragnehmers

  • Leere Zeichenfolge <> NULL
  • Leere Zeichenfolge erfordert 2 Byte Speicher + einen Offset-Lesevorgang
  • NULL verwendet null Bitmap = schneller
  • IDENTITÄT beginnt nicht immer bei 1 (warum die Hälfte Ihrer Reichweite verschwenden?)

Das gesamte Konzept ist gemäß den meisten anderen Antworten hier fehlerhaft

gbn
quelle
4
Obwohl; Soweit ich mich erinnere, eine leere Zeichenfolge ist NULL in Oracle.
MatBailie
1

Während ich 'Z' nie als magischen Wert für Null gesehen habe, habe ich 'X' gesehen, um ein Feld darzustellen, das nicht ausgefüllt wurde. Das heißt, ich habe dies immer nur an einer Stelle und an meiner Schnittstelle gesehen Es handelte sich nicht um eine Datenbank, sondern um eine XML-Datei. Ich wäre also nicht bereit, dies als Argument für die gängige Praxis zu verwenden.

Beachten Sie, dass wir das 'X' speziell behandeln müssen, und wie Dems erwähnt hat, müssen wir es dokumentieren, und die Leute waren verwirrt. Zu unserer Verteidigung wird uns dies von einem externen Lieferanten aufgezwungen, nicht etwas, das wir uns selbst ausgedacht haben!

Paul Wagland
quelle
Dies wäre sehr verwirrend für Datenbanken, in denen Auswahlmöglichkeiten für Kontrollkästchen gespeichert sind, die mit einem Zeichenfeld von 'X' und nicht mit '' (Leerzeichen) markiert sind. Ich hoffe, Antimaterie und Materie werden nicht in dieselbe Datenbank gemischt ...
Wallyk
Ich denke, dies hat keine Stimmen erhalten, da es nicht direkt mit der ursprünglichen Frage zum Datenbankdesign zusammenhängt, aber ich muss zumindest sagen, dass selbst diese "tangentiale" Antwort nur dazu dient, die Absurdität des Ansatzes des Auftragnehmers zu unterstreichen. (Auch ich denke, dass "No Votes" von hier an durch "Z" ersetzt werden sollte.)
Boris Nikolaevich
Die einzige Antwort auf die Frage.
Pindatjuh