Devo armazenar Falso como Nulo em um campo de banco de dados booleano?

20

Digamos que você tenha um aplicativo que tenha um campo booleano em sua Usertabela chamado Inactive.

Existe algo inerentemente errado em apenas armazenar falso como nulo? Em caso afirmativo, você pode explicar qual deve ser o lado negativo? Eu discuti isso com alguém há alguns meses e nós dois concordamos que não deveria importar, desde que você faça isso de forma consistente em todo o aplicativo / banco de dados. Recentemente, alguém que eu conheço enfatizou que "verdadeiro" trueou falsedeveria ser usado, mas na verdade não explicava o porquê.

Ominus
fonte
25
A Wikipedia diz 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 é a sabedoria aceita e você não deve redefinir o que Null significa em seu aplicativo. Será confuso para todos os outros que trabalham com seu código.
PersonalNexus
10
Por que você quer fazer isso? Por que não usar apenas um campo de bits não nulo e definir o padrão como false se esse é o comportamento que você deseja, em vez de confundir o problema com um campo de três estados?
31412 JohnFx
5
Exemplo do mundo real de por que é uma péssima idéia: SELECT * FROM foo WHERE bar = FALSEnão dá os resultados que você espera.
Blrfl
2
Considere usar uma coluna int com o padrão 0 em vez de booleano. Dessa forma, se surgirem novas condições (talvez um estado 'pendente', por exemplo), você não precisará alterar a estrutura do banco de dados.
GrandmasterB
4
Mas se você armazenar false como null, como vai armazenar FILE_NOT_FOUND ?! ( thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx )
Ed James

Respostas:

50

Existe algo inerentemente errado em apenas armazenar falso como nulo?

Sim.

Em caso afirmativo, você pode explicar qual deve ser o lado negativo?

NULL não é o mesmo que False.

Por definição, comparações (e lógicas) que envolvem NULL devem retornar valores de NULL (não False). No entanto, as implementações de SQL podem variar.

True and NULL é NULL (não falso).

True and NULL or False é NULL (não falso).

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

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

S.Lott
fonte
3
Explique sucintamente por que NULL é o valor que representa a ausência de valor.
Maple_shaft
2
o primeiro dia do meu primeiro trabalho de desenvolvimento envolveu a depuração e corrigir um erro como neste pergunta / resposta, reminiscência +1
tsundoku
1
Observe que o próprio artigo ao qual você vinculou diz que, se nullfor irrelevante para a lógica (como é o caso em whatever OR TRUEou whatever AND FALSEonde nenhum valor de whateverpode alterar a condição), a expressão retornará um valor. Não é uma otimização; é assim que a lógica de 3 valores funciona . Qualquer DBMS que insista em retornar UNKNOWN/ NULLpara essas expressões é fundamentalmente quebrado.
cHao 6/02/12
1
@ S.Lott, mas o armazenamento nulo em vez de falso economiza espaço?
Azerafati
2
@ Bludream: Para booleanos, um campo anulável pode realmente ocupar mais espaço, dependendo do DBMS. (É uma quantidade insignificante em quase todos os casos.) Um booleano pode ser representado em um único bit ... mas um booleano anulável possui três valores possíveis (verdadeiro, falso e nulo) e, portanto, precisa de mais de um bit.
cHao 11/07
15

Ao permitir nulos em um campo booleano, você está transformando uma representação binária pretendida (verdadeiro / falso) em uma representação em três estados (verdadeiro, falso, nulo) em que suas entradas 'nulas' são indeterminadas. O valor 'nulo' não é apropriadamente 'verdadeiro' nem 'falso'. Que razão você teria para aumentar sua representação para ser imprecisa?

Mesmo se você optar por um padrão como esse e fazê-lo de forma consistente em todo o aplicativo, isso não o fará bem. Você acabará em uma situação em que não está claro para os olhos novos por que esse padrão está no lugar ou, mais provavelmente, acabará em uma situação em que esse padrão foi inadvertidamente quebrado.

Jacob Maristany
fonte
5

O que os outros disseram. 3 valores possíveis não são booleanos.

Mas você pode ter uma necessidade legítima de 3 valores. Tais como (verdadeiro, falso, desconhecido). Mesmo se esse for o caso, se você estiver em ultra-normalização, não permitirá nenhum valor nulo. Em vez disso, você armazenará um verdadeiro booleano em outra tabela com uma relação de 1 para 1. Um valor nulo pode ser produzido em uma consulta por uma associação externa "com falha", não por um valor nulo armazenado fisicamente.

Lord Tydus
fonte
fora do domínio da minha pergunta booleana, por que verdadeiro falso desconhecido seria ruim se você usasse null para fazer isso? Além da minha pergunta, os nulos geralmente devem ser evitados? Por quê?
ominus
3
@ Minus: Nulos geralmente devem ser evitados se você é um purista. Se usado como deveria ser usado (como "não há valor aqui" e não como falso-falso false), eles terão seu lugar. Se não, eles não existiriam. A alternativa, como mencionado, é basicamente ter uma tabela inteira com apenas a chave primária da sua linha e um único booleano (ou int, ou varchar, ou o que você tem). Para cada campo que você tornaria anulável. Embora seja relacionalmente puro, é complicado demais para a maioria dos propósitos.
cHao 07/02
-3

É bool?um tipo booleano? Não. É do tipo Nullable<T>onde Té booleano. Um booleano anulável pode ter 3 valores: verdadeiro, falso e nulo. Para usar boolou bool?depende de sua exigência. Pode haver uma razão legítima na qual você pode precisar usar nulo, mas um tipo que cheira a binário, mas você não sabe a resposta. No exemplo acima,User.IsActiveparece bem claro. O usuário está ativo ou não. Como sistema, talvez você queira saber se um usuário está ativo ou não. Não deve haver 'talvez'. Mas pense em algo como um sinalizador de recurso. O recurso está ativado? As respostas podem ser sim, não ou não tenho certeza. Você pode ter uma regra comercial que soletre apenas o botão quando o sinalizador estiver definido como verdadeiro. Alguém pode argumentar que bool é por padrão false, então por que criar bool anulável? Inverta o requisito: você definirá todos os valores na fonte de dados como true?

nullableTypes
fonte
2
é difícil ler este post (parede de texto). Você se importaria de editá -lo em uma forma melhor?
Gnat #