Soll ich False als Null in einem booleschen Datenbankfeld speichern?

20

Angenommen, Sie haben eine Anwendung, deren UserTabelle ein boolesches Feld enthält Inactive.

Ist irgendetwas inhärent falsch daran, nur false als null zu speichern? Wenn ja, können Sie bitte erklären, was der Nachteil sein sollte? Ich habe dies vor ein paar Monaten mit jemandem besprochen, und wir waren uns einig, dass es keine Rolle spielen sollte, solange Sie dies in der gesamten App / Datenbank konsequent tun. Jemand, den ich kenne, hat kürzlich nachdrücklich betont, dass "wahr" ist trueoder falseverwendet werden sollte, aber er hat nicht wirklich erklärt, warum.

Ominus
quelle
25
Wikipedia sagt, dass Null is a special marker used in Structured Query Language (SQL) to indicate that a data value does not exist in the database dies die akzeptierte Weisheit ist und Sie nicht neu definieren sollten, was Null in Ihrer Bewerbung bedeutet. Es wird verwirrend für alle anderen sein, die mit Ihrem Code arbeiten.
PersonalNexus
10
Warum willst du das überhaupt? Warum nicht einfach ein nicht nullwertfähiges Bitfeld verwenden und den Standardwert auf false setzen, wenn dies das gewünschte Verhalten ist, anstatt das Problem mit einem Tri-State-Feld zu verwechseln?
JohnFx
5
Ein Beispiel aus der Praxis, warum dies eine sehr schlechte Idee ist: SELECT * FROM foo WHERE bar = FALSEGeben Sie nicht die Ergebnisse an, die Sie erwarten.
Blrfl
2
Verwenden Sie eine int-Spalte mit dem Standardwert 0 anstelle eines Booleschen Werts. Auf diese Weise müssen Sie die Datenbankstruktur nicht ändern, wenn neue Bedingungen auftreten (z. B. der Status "Ausstehend").
GroßmeisterB
4
Aber wenn Sie false als null speichern, wie werden Sie dann FILE_NOT_FOUND speichern ?! ( thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx )
Ed James

Antworten:

51

Ist irgendetwas an sich falsch daran, nur false als null zu speichern?

Ja.

Wenn ja, können Sie bitte erklären, was der Nachteil sein sollte?

NULL ist nicht dasselbe wie Falsch.

Per Definition sollten Vergleiche (und Logik), die NULL beinhalten, Werte von NULL (nicht False) zurückgeben. SQL-Implementierungen können jedoch variieren.

True and NULL ist NULL (nicht falsch).

True and NULL or False ist NULL (nicht falsch).

http://en.wikipedia.org/wiki/Null_(SQL)#Three-valued_logic_.283VL.29

http://technet.microsoft.com/en-us/library/cc966426.aspx

S.Lott
quelle
3
Kurze Erklärung, warum NULL der Wert ist, der das Fehlen von Wert darstellt.
maple_shaft
2
Der erste Tag meines ersten Entwicklungsjobs umfasste das Debuggen und Beheben eines Fehlers wie in dieser Frage / Antwort, Reminiszenz +1
Tsundoku
1
Beachten Sie, dass genau in dem Artikel, mit dem Sie verlinkt haben, angegeben wird, dass der Ausdruck einen Wert zurückgibt , wenn das nullfür die Logik irrelevant ist (wie dies in whatever OR TRUEoder der Fall ist whatever AND FALSE, wenn kein Wert whateverdie Bedingung ändern kann). Es ist keine Optimierung; So funktioniert 3-wertige Logik . Jedes DBMS, das darauf besteht, UNKNOWN/ NULLfür diese Ausdrücke zurückzugeben, ist grundsätzlich fehlerhaft.
CHAO
1
@ S.lott, aber speichere nicht null statt falsch speichere etwas platz ???
Azerafati
2
@Bludream: Bei Booleschen Werten kann ein nullwertfähiges Feld je nach DBMS tatsächlich mehr Platz beanspruchen . (Dies ist jedoch in fast allen Fällen eine vernachlässigbare Menge.) Ein Boolescher Wert kann in einem einzelnen Bit dargestellt werden. Ein nullbarer Boolescher Wert hat drei mögliche Werte (true, false und null) und benötigt daher mehr als ein Bit.
CHAO
15

Indem Sie Nullen in einem booleschen Feld zulassen, wandeln Sie eine beabsichtigte Binärdarstellung (wahr / falsch) in eine Darstellung mit drei Zuständen (wahr, falsch, null) um, bei der Ihre 'Null'-Einträge unbestimmt sind. Der Wert 'null' ist weder entsprechend 'wahr' noch 'falsch'. Aus welchem ​​Grund müssten Sie Ihre Darstellung erweitern, um ungenau zu sein?

Selbst wenn Sie sich für ein Muster wie dieses entscheiden und es in Ihrer gesamten Anwendung konsequent ausführen, ist dies nicht in Ordnung. Sie werden in einer Situation enden, in der es für neue Augen nicht klar ist, warum dieses Muster vorhanden ist, oder, wahrscheinlicher, in einer Situation, in der dieses Muster versehentlich gebrochen wird.

Jacob Maristany
quelle
5

Was andere gesagt haben. 3 mögliche Werte sind keine Booleschen Werte.

Möglicherweise benötigen Sie jedoch 3 Werte. Wie (wahr, falsch, unbekannt). Selbst wenn dies der Fall ist, werden Sie, wenn Sie sich in der Ultra-Normalisierung befinden, überhaupt keine Nullwerte zulassen. Stattdessen speichern Sie einen echten Booleschen Wert in einer anderen Tabelle mit einer 1: 1-Beziehung. Ein Nullwert könnte in einer Abfrage durch einen "fehlgeschlagenen" Outer Join erzeugt werden, nicht durch einen physikalisch gespeicherten Nullwert.

Lord Tydus
quelle
außerhalb des Bereichs meiner booleschen Frage, warum wahr falsch unbekannt schlecht wäre, wenn Sie null verwenden würden, um es zu tun? Jenseits meiner Frage sind Nullen generell zu vermeiden? Warum?
Ominus
3
@Ominus: Nullen sind im Allgemeinen zu vermeiden, wenn Sie ein Purist sind. Wenn sie so verwendet werden, wie sie verwendet werden sollen (als "hier gibt es keinen Wert" anstatt als Fälschung false), dann haben sie ihren Platz. Andernfalls würden sie nicht existieren. Die Alternative besteht, wie bereits erwähnt, im Grunde darin, eine ganze andere Tabelle mit nur dem Primärschlüssel Ihrer Zeile und einem einzelnen Booleschen Wert (oder int, oder varchar, oder was haben Sie) zu haben. Für jedes Feld, das Sie andernfalls als nullwertfähig festlegen würden. Obwohl relational rein, ist es für die meisten Zwecke zu verworren.
CHAO
-3

Ist bool?ein Boolescher Typ? Nein. Es ist ein Typ, Nullable<T>bei dem Tes sich um einen Booleschen Wert handelt. Ein nullwertfähiger Boolescher Wert kann drei Werte haben: true, false und null. Zu verwenden booloder bool?hängt von ihrer anforderung. Es könnte einen legitimen Grund geben, aus dem Sie möglicherweise null verwenden müssen, aber einen Typ, der nach binär riecht, dessen Antwort Sie jedoch nicht kennen. Im obigen BeispielUser.IsActivescheint eindeutig zu sein. Benutzer ist aktiv oder nicht. Als System möchte es möglicherweise wissen, ob ein Benutzer aktiv ist oder nicht. Es sollte kein "Vielleicht" geben. Denken Sie aber an so etwas wie ein Feature-Flag. Ist die Funktion aktiviert? Die Antworten könnten ja, nein oder nicht sicher sein. Möglicherweise haben Sie eine Geschäftsregel, die nur dann die Schaltfläche anzeigt, wenn das Flag auf true gesetzt ist. Man kann argumentieren, Bool ist standardmäßig false. Warum sollte man also einen nullfähigen Bool erstellen? Umgekehrt die Anforderung: Werden Sie alle Werte in der Datenquelle auf true setzen?

nullableTypes
quelle
2
Dieser Beitrag ist ziemlich schwer zu lesen (Textwand). Hätten Sie etwas dagegen bearbeiten sie in eine bessere Form ing?
Mücke