Ich erinnere mich, dass ich diesen einen Artikel über das Datenbankdesign gelesen habe, und ich erinnere mich auch, dass gesagt wurde, Sie sollten Feldeigenschaften von NOT NULL haben. Ich weiß nicht mehr, warum das so war.
Alles, woran ich denken kann, ist, dass Sie als Anwendungsentwickler nicht auf NULL und einen möglicherweise nicht vorhandenen Datenwert (z. B. eine leere Zeichenfolge für Zeichenfolgen) testen müssen .
Was tun Sie bei Datum, Uhrzeit und Datum (SQL Server 2008)? Sie müssten ein historisches Datum oder ein Datum mit Talsohle verwenden.
Irgendwelche Ideen dazu?
database-design
null
Thomas Stringer
quelle
quelle
Antworten:
Ich denke, die Frage ist schlecht formuliert, da der Wortlaut impliziert, dass Sie bereits entschieden haben, dass NULLs schlecht sind. Vielleicht meinten Sie "Sollen wir NULL zulassen?"
Wie auch immer, hier ist meine Sichtweise: Ich denke, NULLs sind eine gute Sache. Wenn Sie NULLs verhindern, nur weil "NULLs sind schlecht" oder "NULLs sind hart", beginnen Sie, Daten zu erstellen. Was ist zum Beispiel, wenn Sie mein Geburtsdatum nicht kennen? Was werden Sie in die Spalte setzen, bis Sie wissen? Wenn Sie so etwas wie Anti-NULL-Leute sind, geben Sie 1900-01-01 ein. Jetzt werde ich in die Geriatrie eingewiesen und wahrscheinlich einen Anruf von meinem lokalen Nachrichtensender erhalten.
Wenn eine Zeile eingegeben werden kann, in der Sie möglicherweise den Wert einer Spalte nicht kennen , ist NULL meiner Meinung nach viel sinnvoller, als einen beliebigen Token-Wert auszuwählen, um die Tatsache darzustellen, dass er unbekannt ist - ein Wert, den andere angeben müssen bereits wissen, zurückentwickeln oder nachfragen, um herauszufinden, was es bedeutet.
Es besteht jedoch ein Gleichgewicht - nicht jede Spalte in Ihrem Datenmodell sollte nullwertfähig sein. Es gibt häufig optionale Felder in einem Formular oder Informationen, die ansonsten zum Zeitpunkt der Erstellung der Zeile nicht erfasst werden. Dies bedeutet jedoch nicht, dass Sie das Auffüllen aller Daten verschieben können. :-)
Auch die Fähigkeit, NULL zu verwenden, kann durch entscheidende Anforderungen im wirklichen Leben eingeschränkt sein. Im medizinischen Bereich kann es beispielsweise lebenswichtig sein, zu wissen, warum ein Wert unbekannt ist. Ist die Herzfrequenz NULL, weil es keinen Puls gab oder weil wir ihn noch nicht gemessen haben? Können wir in einem solchen Fall NULL in die Herzfrequenzspalte setzen und Notizen oder eine andere Spalte mit einem NULL-Grund haben?
Haben Sie keine Angst vor Nullen, sondern sind Sie bereit zu lernen oder zu diktieren, wann und wo sie verwendet werden sollen und wann und wo nicht.
quelle
birth_date
in der Sie Geburtsdaten speichern? Wenn das Geburtsdatum unbekannt ist, geben Sie einfach kein Geburtsdatum in einbirth_date
. Nullen sind eine Katastrophe.1900-01-01
, um einen NULL-Wert für Datum und Uhrzeit zu vermeiden? OK dann. Auch NULL = unbekannt und unbekannt = falsch. Ich bin mir nicht sicher, welche Probleme dies verursachen könnte, außer dass Menschen nicht mit diesem Wissen geboren werden (als ob sie nicht mit vielen Dingen geboren würden, die einem komplexen RDBMS inhärent sind). Wieder winkte er mit den Händen und sagte: "Problem! Katastrophe!" macht es nicht so.Gründe dafür sind:
NULL ist kein Wert und hat daher keinen intrinsischen Datentyp. Nullen müssen überall speziell behandelt werden, wenn Code, der sich ansonsten auf tatsächliche Typen stützt, möglicherweise auch den nicht typisierten NULL- Wert erhält.
NULL bricht die Zwei-Wert-Logik (vertrautes Wahr oder Falsch) und erfordert eine Drei-Wert-Logik. Die korrekte Implementierung ist weitaus komplexer und wird von den meisten Datenbankadministratoren und fast allen Nicht-Datenbankadministratoren nur schlecht verstanden. Infolgedessen werden viele subtile Fehler in der Anwendung positiv hervorgerufen .
Die semantische Bedeutung eines bestimmten NULL-Werts bleibt im Gegensatz zu tatsächlichen Werten der Anwendung überlassen .
Semantiken wie "nicht zutreffend" und "unbekannt" und "Sentinel" sind üblich, und es gibt auch andere. Sie werden häufig gleichzeitig in derselben Datenbank verwendet, auch in derselben Beziehung. und sind natürlich unerklärliche und ununterscheidbare und inkompatible Bedeutungen.
Sie sind für relationale Datenbanken nicht erforderlich , wie in „Umgang mit fehlenden Informationen ohne Nullen“ erläutert . Eine weitere Normalisierung ist ein offensichtlicher erster Schritt, um eine Tabelle mit NULL-Werten zu löschen.
Dies bedeutet nicht, dass NULL niemals erlaubt sein sollte. Es wird argumentiert, dass es viele gute Gründe gibt, NULL zu verbieten, wo immer dies möglich ist.
Bezeichnenderweise argumentiert es sehr schwer für den Versuch - durch eine bessere Schema - Design und eine bessere Datenbank - Engines, und eine noch bessere Datenbanksprachen - machen es möglich , NULL oft mehr zu vermeiden.
Fabian Pascal antwortet auf eine Reihe von Argumenten in „Nulls Nullified“ .
quelle
Ich bin anderer Meinung, Nullen sind ein wesentliches Element des Datenbankdesigns. Die Alternative wäre, wie Sie auch angedeutet haben, eine Verbreitung bekannter Werte, um das Vermisste oder Unbekannte darzustellen. Das Problem liegt darin, dass null so häufig missverstanden und infolgedessen unangemessen verwendet wird.
Das IIRC, Codd, schlug vor, die derzeitige Implementierung von Null (dh nicht vorhanden / nicht vorhanden) zu verbessern, indem zwei Nullmarkierungen anstelle einer "nicht vorhanden, aber anwendbar" und "nicht vorhanden und nicht anwendbar" verwendet werden. Ich kann mir nicht vorstellen, wie sich relationale Designs dadurch persönlich verbessern lassen.
quelle
null
und eine benutzerdefinierte mehrwertige Logik zu verwenden: pLassen Sie mich zunächst sagen, ich bin kein DBA, ich bin auswendig ein Entwickler und ich pflege und aktualisiere unsere Datenbanken basierend auf unseren Bedürfnissen. Davon abgesehen hatte ich aus ein paar Gründen die gleiche Frage.
Ich verbringe sehr viel Zeit damit, die zahlreichen Antworten, Kommentare, Artikel und Ratschläge im Internet zu durchsuchen. Es erübrigt sich zu erwähnen, dass die meisten Informationen in etwa der Antwort von @ AaronBertrand entsprachen. Aus diesem Grund hatte ich das Bedürfnis, auf diese Frage zu antworten.
Zunächst möchte ich etwas klarstellen für alle zukünftigen Leser ... NULL-Werte stehen für unbekannte Daten, NICHT für unbenutzte Daten. Wenn Sie eine Mitarbeitertabelle mit einem Kündigungsdatum haben. Ein Nullwert für das Beendigungsdatum ist ein zukünftig erforderliches Feld, das derzeit nicht bekannt ist. Jedem aktiven oder gekündigten Mitarbeiter wird irgendwann ein Datum hinzugefügt. Das ist meiner Meinung nach der einzige Grund für ein Nullable-Feld.
Davon abgesehen würde dieselbe Mitarbeitertabelle höchstwahrscheinlich eine Art Authentifizierungsdaten enthalten. In einer Unternehmensumgebung ist es üblich, dass Mitarbeiter in der Datenbank für Personalwesen und Buchhaltung aufgeführt werden, jedoch nicht immer über Authentifizierungsdetails verfügen oder diese benötigen. Die meisten Antworten lassen Sie glauben, dass es in Ordnung ist, diese Felder zu löschen oder in einigen Fällen ein Konto für sie zu erstellen, aber niemals die Anmeldeinformationen an sie zu senden. Ersteres veranlasst Ihr Entwicklungsteam, Code zu schreiben, um auf NULL-Werte zu prüfen und entsprechend damit umzugehen, und letzteres birgt ein enormes Sicherheitsrisiko! Konten, die noch nie im System verwendet werden, erhöhen nur die Anzahl der möglichen Zugriffspunkte für einen Hacker. Außerdem belegen sie wertvollen Datenbankspeicherplatz für etwas, das noch nie verwendet wird.
Angesichts der obigen Informationen ist die beste Möglichkeit, mit nullwertfähigen Daten umzugehen, die verwendet werden, nullwertfähige Werte zuzulassen. Es ist traurig, aber wahr, und Ihre Entwickler werden Sie dafür hassen. Der zweite Typ von nullwertfähigen Daten sollte in eine verwandte Tabelle gestellt werden (IE: Konto, Anmeldeinformationen usw.) und eine Eins-zu-Eins-Beziehung haben. Auf diese Weise kann ein Benutzer ohne Anmeldeinformationen existieren, sofern diese nicht benötigt werden. Dies beseitigt das zusätzliche Sicherheitsrisiko und wertvollen Datenbankspeicher und sorgt für eine viel sauberere Datenbank.
Im Folgenden finden Sie eine sehr vereinfachte Tabellenstruktur, die sowohl die erforderliche nullfähige Spalte als auch eine Eins-zu-Eins-Beziehung zeigt.
Ich weiß, dass ich ein wenig zu spät zur Party komme, da diese Frage vor Jahren gestellt wurde, aber hoffentlich hilft dies, etwas Licht in dieses Thema zu bringen und wie man am besten damit umgeht.
quelle
TerminationDate
in den Mitarbeiterdatensätzen gibt, sondern eine Tabelle, fürTerminatedEmployee
die Mitarbeiter von der Anwendung verschoben (nicht kopiert) werden, wenn sie beendet werden. Offensichtlich funktioniert dies sehr gut mit der Account-Tabelle, da keine verknüpften Accounts in derTerminatedEmployee
Tabelle vorhanden sind. Wenn Sie die Telefonnummern weiterhin benötigen, würde ich die Fremdschlüssel umkehren, sodass die Mitarbeiter- und die gekündigten Mitarbeiter-Tabellen die ID der Telefonnummer enthalten und nicht umgekehrt.Abgesehen von all den Problemen mit verwirrenden NULL-Entwicklern haben NULL-Werte einen weiteren schwerwiegenden Nachteil: die Leistung
NULL-fähige Spalten sind aus Sicht der Leistung eine Katastrophe. Betrachten Sie als Beispiel die Ganzzahlarithmetik. In einer vernünftigen Welt ohne NULL ist es "einfach", Integer-Arithmetik im Datenbank-Engine-Code mithilfe von SIMD-Anweisungen zu vektorisieren, um so ziemlich jede Berechnung mit Geschwindigkeiten durchzuführen, die schneller als 1 Zeile pro CPU-Zyklus sind. Sobald Sie jedoch NULL einführen, müssen Sie alle Sonderfälle behandeln, die NULL erstellt. Moderne CPU-Befehlssätze (zu lesen: x86 / x64 / ARM und auch GPU-Logik) sind dafür einfach nicht effizient ausgestattet.
Betrachten Sie Division als Beispiel. Auf einer sehr hohen Ebene ist dies die Logik, die Sie für eine Ganzzahl ungleich Null benötigen:
Mit NULL wird dies etwas kniffliger. Zusammen mit
b
Ihnen benötigen Sie einen Indikator, wennb
null ist und ähnlich füra
. Der Scheck wird nun:Die NULL-Arithmetik ist auf einer modernen CPU wesentlich langsamer als die Nicht-Null-Arithmetik (um den Faktor 2-3x).
Es wird schlimmer, wenn Sie SIMD einführen. Mit SIMD kann eine moderne Intel-CPU 4 x 32-Bit-Integer-Divisionen in einem einzigen Befehl ausführen:
Nun gibt es auch Möglichkeiten, mit NULL im SIMD-Land umzugehen, aber dies erfordert die Verwendung von mehr Vektoren und CPU-Registern und einige clevere Bitmaskierungen. Selbst mit guten Tricks schleicht sich der Performance-Nachteil der NULL-Ganzzahl-Arithmetik für relativ einfache Ausdrücke in den 5-10-fach langsameren Bereich.
So etwas gilt für Aggregate und zum Teil auch für Joins.
Mit anderen Worten: Die Existenz von NULL in SQL ist eine Impedanzinkongruenz zwischen der Datenbanktheorie und dem tatsächlichen Design moderner Computer. Es gibt einen guten Grund, warum NULL Entwickler verwirrt - da eine Ganzzahl in den meisten vernünftigen Programmiersprachen nicht NULL sein kann -, funktioniert Computer einfach nicht.
quelle
Interessante Fragen.
Es ist komplizierter als das. Null hat eine Reihe von unterschiedlichen Bedeutungen und ein wirklich wichtiger Grund, Nullen in vielen Spalten nicht zuzulassen, ist, dass, wenn die Spalte null ist, dies eine und nur eine Sache bedeutet (nämlich, dass sie nicht in einem Outer Join aufgetaucht ist). Außerdem können Sie Mindeststandards für die Dateneingabe festlegen, was sehr hilfreich ist.
Das zeigt ein Problem mit Nullen auf Anhieb, nämlich dass ein in einer Tabelle gespeicherter Wert entweder "Dieser Wert gilt nicht" oder "Wir wissen es nicht" bedeuten kann. Bei Zeichenfolgen kann eine leere Zeichenfolge als "dies gilt nicht" dienen. Bei Datums- und Uhrzeitangaben gibt es jedoch keine solche Konvention, da es keinen gültigen Wert gibt, was dies üblicherweise bedeutet. In der Regel bleiben Sie dort mit NULL-Werten stecken.
Es gibt Möglichkeiten, dies zu umgehen (indem Sie mehr Relationen und Verknüpfungen hinzufügen), aber diese werfen genau dieselben semantischen Klarheitsprobleme auf wie NULL-Werte in der Datenbank. Für diese Datenbanken würde ich mir darüber keine Sorgen machen. Es gibt einfach nichts, was Sie wirklich dagegen tun können.
EDIT: Ein Bereich , wo NULLs sind unverzichtbar in Fremdschlüssel. Hier haben sie normalerweise nur eine Bedeutung, die mit der Null in der äußeren Verknüpfungsbedeutung identisch ist. Dies ist natürlich eine Ausnahme vom Problem.
quelle
Der Wikipedia-Artikel zu SQL Null enthält einige interessante Anmerkungen zum NULL-Wert. Als datenbankunabhängige Antwort können Sie NULL-Werte für Ihr spezifisches RDBMS verwenden, sofern Sie die möglichen Auswirkungen kennen. Wenn dies nicht der Fall wäre, könnten Sie Spalten nicht als nullfähig angeben.
Beachten Sie nur, wie Ihr RDBMS sie in SELECT-Operationen wie Mathematik und auch in Indizes behandelt.
quelle
Wow, die richtige Antwort "Lassen Sie keine NULL-Werte zu, wenn Sie das nicht müssen, weil sie die Leistung beeinträchtigen" ist irgendwie die zuletzt bewertete Antwort. Ich werde es unterstützen und ausarbeiten. Wenn ein RDBMS NULL für eine Spalte mit geringer Dichte zulässt, wird diese Spalte zu einer Bitmap hinzugefügt, in der nachverfolgt wird, ob der Wert für jede einzelne Zeile NULL ist. Wenn Sie also einer Spalte in einer Tabelle die NULL-Fähigkeit hinzufügen, in der alle Spalten keine NULL-Werte zulassen, erhöhen Sie den zum Speichern der Tabelle erforderlichen Speicherplatz. Außerdem muss das RDBMS die Bitmap lesen und darauf schreiben, was die Leistung bei allen Vorgängen beeinträchtigt.
In einigen Fällen kann das Zulassen von NULL 3NF unterbrechen. Stellen Sie sich das folgende Szenario vor, obwohl ich nicht wie viele meiner Kollegen ein Fan von 3NF bin:
In der Personentabelle gibt es eine Spalte mit dem Namen DateOfDeath, die auf Null gesetzt werden kann. Wenn eine Person gestorben ist, wird sie mit ihrem DateOfDeath ausgefüllt, andernfalls bleibt sie NULL. Es gibt auch eine nicht nullfähige Bitspalte mit dem Namen IsAlive. Diese Spalte wird auf 1 gesetzt, wenn die Person lebt, und auf 0, wenn die Person tot ist. Die überwiegende Mehrheit der gespeicherten Prozeduren verwendet die Spalte "IsAlive". Sie kümmern sich nur darum, ob eine Person am Leben ist, nicht um ihr DateOfDeath.
Die Spalte IsAlive unterbricht jedoch die Datenbanknormalisierung, da sie vollständig von DateOfDeath abgeleitet werden kann. Da IsAlive jedoch in den meisten SPs fest verdrahtet ist, besteht die einfache Lösung darin, DateOfDeath nicht auf Null zu setzen und der Spalte einen Standardwert zuzuweisen, falls die Person noch am Leben ist. Die wenigen SPs, die DateOfDeath verwenden, können dann umgeschrieben werden, um die IsAlive-Spalte zu überprüfen und das DateOfDeath nur dann zu berücksichtigen, wenn die Person nicht am Leben ist. Da sich die Mehrheit der SPs nur um IsAlive (ein bisschen) und nicht um DateOfDeath (ein Datum) kümmert, wird der Zugriff mit diesem Muster erheblich beschleunigt.
Ein nützliches T-SQL-Skript zum Auffinden nullbarer Spalten ohne NULL-Werte in allen Schemata ist:
Wenn Sie dies auf einer Kopie Ihrer Produktionsdatenbank ausführen, finden Sie die Spaltenentwickler, die so markiert sind, dass sie NULL-Werte zulassen, die in der Praxis keine NULL-Werte haben. Die überwiegende Mehrheit von diesen kann als NOT NULL markiert werden, wodurch die Leistung erhöht und der Speicherplatz verringert wird.
Es ist möglicherweise nicht möglich, alle NULL-Werte in allen Tabellen zu entfernen, und das Design bleibt übersichtlich. Es ist jedoch von großem Vorteil, so viele NULL-Werte wie möglich zu entfernen. Der Optimierer arbeitet mit diesen Informationen viel schneller, und wenn Sie alle NULL-Werte in einer Tabelle entfernen können, können Sie beträchtlichen Speicherplatz zurückgewinnen.
Ich weiß, dass Datenbankadministratoren über Leistung nicht allzu viel nachdenken, aber Sie können nur eine begrenzte Menge an Arbeitsspeicher und Prozessorleistung in eine Lösung stecken, und irgendwann müssen Sie sich Gedanken über das logische und physische Design machen .
Beachten Sie auch, dass dies nur für echte RDBMS gilt und ich den technischen Teil meiner Antworten auf SQL Server beziehe. Das aufgelistete T-SQL zum Auffinden nullfähiger Spalten ohne Nullen stammt ebenfalls von SQL Server.
quelle