¿Debo almacenar False as Null en un campo de base de datos booleana?

20

Digamos que tiene una aplicación que tiene un campo booleano en su Usertabla llamada Inactive.

¿Hay algo inherentemente incorrecto con solo almacenar falso como nulo? Si es así, ¿puede explicar cuál debería ser el lado negativo? He discutido esto con alguien hace unos meses y ambos acordamos que no debería importar siempre y cuando lo hagas de manera consistente en toda la aplicación / base de datos. Recientemente, alguien que conozco enfatizó que "verdadero" trueo falsedebería usarse, pero realmente no dieron una explicación de por qué.

Ominus
fuente
25
Wikipedia dice que Null is a special marker used in Structured Query Language (SQL) to indicate that a data value does not exist in the database esta es la sabiduría aceptada y no debe redefinir lo que significa Nulo en su aplicación. Será confuso para todos los demás que trabajen con su código.
PersonalNexus
10
¿Por qué incluso QUIERES hacer esto? ¿Por qué no usar un campo de bit no anulable y establecer el valor predeterminado en falso si ese es el comportamiento que desea en lugar de confundir el problema con un campo de tres estados?
JohnFx
55
Ejemplo del mundo real de por qué es una muy mala idea: SELECT * FROM foo WHERE bar = FALSEno da los resultados que espera.
Blrfl
2
Considere usar una columna int con un valor predeterminado de 0 en lugar de boolean. De esta manera, si surgen nuevas condiciones (tal vez un estado 'pendiente', por ejemplo), no tiene que alterar la estructura de la base de datos.
GrandmasterB
44
Pero si almacena falso como nulo, ¿cómo va a almacenar FILE_NOT_FOUND? ( thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx )
Ed James

Respuestas:

50

¿Hay algo inherentemente incorrecto con solo almacenar falso como nulo?

Si.

Si es así, ¿puede explicar cuál debería ser el lado negativo?

NULL no es lo mismo que False.

Por definición, las comparaciones (y la lógica) que involucran NULL deberían devolver valores de NULL (no False). Sin embargo, las implementaciones de SQL pueden variar.

True and NULL es NULL (no es falso).

True and NULL or False es NULL (no es falso).

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

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

S.Lott
fuente
3
Explicación sucinta sobre por qué NULL es el valor que representa la ausencia de valor.
maple_shaft
2
el primer día de mi primer trabajo de desarrollo consistió en depurar y corregir un error como en esta pregunta / respuesta, reminiscencia +1
tsundoku
1
Tenga en cuenta que el mismo artículo al que se vinculó dice que si el nulles irrelevante para la lógica (como es el caso en whatever OR TRUEo whatever AND FALSE, donde ningún valor de whateverpuede cambiar la condición), entonces la expresión devuelve un valor. No es una optimización; así es como funciona la lógica de 3 valores . Cualquier DBMS que insista en devolver UNKNOWN/ NULLpara esas expresiones está fundamentalmente roto.
cHao
1
@ S.Lott, pero no almacena nulo en lugar de falso ¿ahorra algo de espacio?
azerafati
2
@Bludream: para los booleanos, un campo anulable puede ocupar más espacio, dependiendo del DBMS. (Sin embargo, es una cantidad insignificante en casi todos los casos). Un booleano se puede representar en un solo bit ... pero un booleano anulable tiene tres valores posibles (verdadero, falso y nulo), y por lo tanto necesita más de un bit.
cHao
15

Al permitir nulos en un campo booleano, está convirtiendo una representación binaria prevista (verdadero / falso) en una representación de tres estados (verdadero, falso, nulo) donde sus entradas 'nulas' son indeterminadas. El valor 'nulo' no es apropiadamente 'verdadero' ni 'falso'. ¿Qué razón tendrías para aumentar tu representación para ser inexacta?

Incluso si decide un patrón como este y lo hace de manera consistente a lo largo de su aplicación, eso no lo hace correcto. Terminará en una situación en la que no está claro para los ojos nuevos por qué ese patrón está en su lugar o, lo más probable, terminará en una situación en la que ese patrón se rompe inadvertidamente.

Jacob Maristany
fuente
5

Lo que otros han dicho. 3 valores posibles no son booleanos.

Pero es posible que tenga una necesidad legítima de 3 valores. Tales como (verdadero, falso, desconocido). Incluso si este es el caso, si está en ultra-normalización, no permitirá ningún valor nulo en absoluto. En su lugar, almacenará un verdadero booleano en otra tabla con una relación de 1 a 1. Se podría generar un valor nulo en una consulta mediante una unión externa "fallida", no mediante un valor nulo almacenado físicamente.

Lord Tydus
fuente
fuera del ámbito de mi pregunta booleana, ¿por qué sería verdadero falso falso desconocido si usas nulo para hacerlo? Más allá de mi pregunta, ¿generalmente se deben evitar los nulos? ¿Por qué?
Ominus
3
@Ominus: los valores nulos generalmente se deben evitar si eres un purista. Si se usan como se supone que se usarán (como "aquí no hay valor" en lugar de como una falsificación falsa false), entonces tienen su lugar. Si no lo hicieran, no existirían. La alternativa, como se mencionó, es básicamente tener una tabla completamente diferente con solo la clave principal de su fila y un único booleano (o int, o varchar, o lo que sea). Para todos y cada uno de los campos que de lo contrario haría nulables. Aunque relacionalmente puro, es demasiado complicado para la mayoría de los propósitos.
cHao
-3

¿Es bool?un tipo booleano? No. Es de tipo Nullable<T>donde Tes booleano. Un booleano anulable puede tener 3 valores: verdadero, falso y nulo. Para usar boolo bool?depende de su requerimiento. Podría haber una razón legítima en la que necesite usar nulo pero un tipo que huele a binario pero no sabe la respuesta. En el ejemplo anterior,User.IsActiveParece claro. El usuario está activo o no. Como sistema, es posible que desee saber si un usuario está activo o no. No debería haber "tal vez". Pero piense en algo como una bandera de características. ¿Está activada la función? Las respuestas podrían ser sí, no o no estoy seguro. Es posible que tenga una regla comercial que especifique que solo se muestra el botón cuando el indicador se establece en verdadero. Uno puede argumentar que bool es por defecto falso, entonces ¿por qué crear bool anulable? Invierta el requisito: ¿va a establecer todos los valores en el origen de datos en verdadero?

nullableTypes
fuente
2
esta publicación es bastante difícil de leer (muro de texto). ¿Te importaría editarlo en una mejor forma?
mosquito