Sei que esse assunto é um pouco polêmico e há muitos artigos / opiniões circulando pela Internet. Infelizmente, a maioria deles assume que a pessoa não sabe qual é a diferença entre NULL e string vazia. Eles contam histórias sobre resultados surpreendentes com junções / agregados e geralmente fazem lições de SQL um pouco mais avançadas. Ao fazer isso, eles perdem completamente o objetivo e são, portanto, inúteis para mim. Portanto, espero que esta pergunta e todas as respostas avancem um pouco no assunto.
Suponhamos que eu tenha uma tabela com informações pessoais (nome, nascimento etc.) em que uma das colunas seja um endereço de email com o tipo varchar. Assumimos que, por algum motivo, algumas pessoas podem não querer fornecer um endereço de email. Ao inserir esses dados (sem email) na tabela, há duas opções disponíveis: defina a célula como NULL ou defina a string vazia (''). Vamos supor que estou ciente de todas as implicações técnicas da escolha de uma solução em detrimento de outra e posso criar consultas SQL corretas para qualquer um dos cenários. O problema é mesmo quando ambos os valores diferem no nível técnico, eles são exatamente os mesmos no nível lógico. Depois de olhar para NULL e '', cheguei a uma única conclusão: não sei o endereço de e-mail do cara. Também não importa o quanto eu tentei, Não consegui enviar um email usando uma seqüência de caracteres nula ou vazia, portanto, aparentemente, a maioria dos servidores SMTP por aí concorda com minha lógica. Então, eu costumo usar NULL onde não sei o valor e considero uma string vazia uma coisa ruim.
Após discussões intensas com os colegas, vim com duas perguntas:
Estou certo ao supor que o uso de uma string vazia para um valor desconhecido está causando um banco de dados "mentir" sobre os fatos? Para ser mais preciso: usando a idéia do SQL de o que é valor e o que não é, posso concluir: temos um endereço de email, apenas descobrindo que não é nulo. Porém, mais tarde, ao tentar enviar um e-mail, chegarei a uma conclusão contraditória: não, não temos endereço de e-mail, esse banco de dados @! # $ Deve estar mentindo!
Existe algum cenário lógico no qual uma string vazia '' possa ser uma transportadora tão boa de informações importantes (além de valor e sem valor), que seria problemático / ineficiente para armazenar de qualquer outra maneira (como coluna adicional). Eu já vi muitas postagens alegando que, às vezes, é bom usar uma string vazia junto com valores reais e NULLs, mas até agora não vi um cenário que fosse lógico (em termos de design do SQL / DB).
PS Algumas pessoas ficam tentadas a responder, que é apenas uma questão de gosto pessoal. Eu não concordo Para mim, é uma decisão de design com consequências importantes. Então, eu gostaria de ver respostas em que a opinião sobre isso é apoiada por alguns motivos lógicos e / ou técnicos.
''
mesmo no Oracle, não é o mesmo queNULL
. Por exemplo, ao atribuir umaCHAR(1)
coluna, o valor''
resultará em' '
(ou seja, um espaço), nãoNULL
. Além disso, se Jacek estava usando Oracle, esta questão provavelmente não até mesmo chegar :-)'' IS NULL
avaliadotrue
em PL / SQL.Respostas:
Eu diria que
NULL
é a escolha correta para "nenhum endereço de email". Existem muitos endereços de email "inválidos" e "" (sequência vazia) é apenas um. Por exemplo, "foo" não é um endereço de email válido, "a @ b @ c" não é válido e assim por diante. Portanto, apenas porque "" não é um endereço de email válido, não há razão para usá-lo como o valor "nenhum endereço de email".Acho que você está certo ao dizer que "" não é a maneira correta de dizer "Não tenho um valor para esta coluna". "" é um valor.
Um exemplo de onde "" pode ser um valor válido, separado para
NULL
o nome do meio de uma pessoa. Nem todo mundo tem um nome do meio, então você precisa diferenciar entre "sem nome do meio" ("" - string vazia) e "Não sei se essa pessoa tem um nome do meio ou não" (NULL
). Provavelmente existem muitos outros exemplos em que uma string vazia ainda é um valor válido para uma coluna.fonte
NULL
que não significa que não há endereço de email, acho que significa que o endereço de email atualmente não é conhecido, não existe ou é impossível preencher por outros motivos. Felizmente, provavelmente não existe uma situação em que alguém queira manter em um banco de dados as informações sobre pessoas que realmente não têm e não planejam ter nenhum endereço de e-mail; caso contrário, um campo booleano separado provavelmente seria necessário.Ao concordar com os comentários acima, eu acrescentaria este argumento como uma motivação principal:
Para fins de codificação intuitiva de auto-documentação, use NULL em vez de cadeias vazias.
fonte
No seu exemplo, se for um valor diretamente do campo da web - eu usaria uma string vazia. Se o usuário puder optar por especificar que ele não deseja fornecer email ou pode excluí-lo -, então NULL.
Aqui estão os links que você pode considerar: https://stackoverflow.com/questions/405909/null-vs-empty-when-dealing-with-user-input/405945#405945
--- editado (em resposta ao comentário de Thomas) ---
Os bancos de dados não vivem sem aplicativos que os utilizam. Definir NULL ou '' não tem valor, se o aplicativo não puder usá-lo corretamente.
Considere um exemplo em que o usuário está preenchendo o formulário LONG e pressione Enter, que enviará uma solicitação persistente ao servidor. Ele pode estar no meio da digitação do email. Provavelmente você deseja armazenar o que ele tem no campo de email, para que mais tarde ele possa finalizá-lo. E se ele inserisse apenas um caractere? E se ele inserisse um caractere e o excluísse? Quando o email não é necessário, algumas vezes os usuários desejam excluí-lo: a maneira mais fácil de limpar o campo. Também no caso de não ser necessário o e-mail, vale a pena validá-lo antes de enviá-lo.
Outro exemplo: o usuário fornece email como spam para @ [bigcompany] .com - nesse caso, não há necessidade de enviar email, mesmo que ele exista e seja válido (e pode até existir). Enviar um desses talvez seja barato, mas se houver 10 mil usuários com esses emails para assinaturas diárias, essa validação poderá economizar muito tempo.
fonte
Acho que a resposta de Dean Hardings cobre isso muito bem. Dito isso, eu gostaria de mencionar que, ao falar sobre NULLs vs strings vazias no nível do banco de dados, você deve pensar sobre seus outros tipos de dados. Você armazenaria a data mínima quando nenhuma data for fornecida? ou -1 quando nenhum int é fornecido? Armazenar um valor quando você não tem valor significa que você deve acompanhar todo um intervalo de valores não. Pelo menos um para cada tipo de dado (possivelmente mais quando você obtém casos em que -1 é um valor real, portanto você precisa ter alguma alternativa etc). Se você precisa / deseja fazer algo "fudgy" no nível do aplicativo, isso é uma coisa, mas não é necessário poluir seus dados.
fonte
Infelizmente, o Oracle confundiu a representação da sequência VARCHAR de comprimento zero com a representação NULL. Ambos são representados internamente por um único byte com valor zero. Isso torna a discussão muito mais difícil.
Muita confusão em torno do NULL gira em torno da lógica de três valores . Considere o seguinte pseudocódigo:
Você não esperaria a terceira mensagem, mas é isso que você receberia, sob três lógicas valiosas. Três lógicas valiosas levam as pessoas a inúmeros erros.
Outra fonte de confusão é extrair inferências a partir da ausência de dados, como extrair uma inferência do cachorro que não latia à noite. Freqüentemente, essas inferências não eram o que o escritor do NULL pretendia transmitir.
Dito isto, há muitas situações em que NULL lida com a ausência de dados muito bem e produz exatamente os resultados desejados. Um exemplo são as chaves estrangeiras nos relacionamentos opcionais. Se você usar um NULL para indicar nenhum relacionamento em uma determinada linha, essa linha será removida de uma junção interna, exatamente como seria de esperar.
Além disso, esteja ciente de que, mesmo que você evite NULLS completamente nos dados armazenados (sexta forma normal), se fizer alguma junção externa, ainda precisará lidar com NULLS.
fonte
Use Nulo.
Não há nenhum ponto em armazenar um valor de '', basta fazer o campo na tabela anulável. Também torna as consultas mais óbvias.
Qual consulta SQL é mais óbvia e legível se você deseja encontrar usuários com um endereço de email?
SELECT * FROM Users WHERE email_address != ''
SELECT * FROM Users WHERE email_address IS NOT NULL
SELECT * FROM Users WHERE email_address != '' and email_address IS NOT NULL
Eu diria que 2 é. Embora 3 seja mais robusto nos casos em que há dados ruins armazenados.
No caso do endereço de email no formulário, que é opcional, ele também deve ser refletido na tabela. No SQL, é um campo anulável, o que significa que não é conhecido.
Não consigo pensar em nenhum valor comercial razoável para armazenar uma string vazia em uma tabela que não seja simplesmente um design ruim. É como armazenar um valor de string de 'NULL' ou 'BLANK', e fazer com que os desenvolvedores assumam que é nulo ou vazio. Para mim, isso é um design ruim. Por que armazenar isso quando há NULL ??
Basta usar NULL e você deixará todo mundo um pouco mais feliz.
MAIS INFORMAÇÕES:
O SQL usa um sistema lógico de três valores: True, False e Unknown.
Para uma explicação melhor e mais detalhada, recomendo que os desenvolvedores leiam: Consultas SQL - além de TRUE e FALSE .
fonte
para a questão técnica específica, o problema não é nulo versus cadeia vazia, é uma falha de validação . Uma string vazia não é um endereço de email válido!
para a pergunta filosófica, a resposta é semelhante: valide suas entradas. Se uma sequência vazia for um valor válido para o campo em questão, espere e codifique; Caso contrário, use null.
Uma string vazia seria uma entrada válida para responder à pergunta: O que a mímica disse à girafa?
fonte
Eu poderia pensar em uma razão para ter NULL e a string vazia:
[email protected]
NULL
Empty String.
No entanto, eu não recomendaria isso e use um campo separado para perguntar se você sabe que não existe nenhum.
fonte
A questão que eu entendo, é quais interpretações de NULL e string vazia devem ser escolhidas. Isso depende de quantos estados o campo particualar pode estar.
A interpretação depende de como o banco de dados está sendo acessado. Se houver uma camada no código que abstraia completamente o banco de dados, a escolha de qualquer política (incluindo dois coulmn) que funcione é completamente aceitável. (Documentar claramente a política é importante). No entanto, se o banco de dados estiver sendo acessado em vários locais, você deverá usar um esquema muito simples, pois o código será mais difícil de manter e poderá estar errado neste caso.
fonte
Bem, basicamente, no nível lógico, não há diferença entre o valor "inválido" e "sem entrada do usuário", eles são apenas "casos especiais" na maioria das vezes. Caso de erro.
Ter nulo requer espaço adicional: ceil (column_with_null / 8) em bytes / por linha.
Célula vazia e nulo são maneiras de marcar que algo está errado / deve ser o padrão. Por que você precisaria de 2 estados "errados"? Por que usar NULLs se eles ocupam espaço adicional e significam exatamente o mesmo que cadeias vazias? Isso apenas introduzirá confusão e redundância quando você tiver duas coisas que significam (o que poderia significar) exatamente o mesmo; é fácil esquecer que você deve usar NULLs em vez de cadeias vazias (se, por exemplo, o usuário omitir alguns campos).
E seus dados podem se tornar uma bagunça. Em um mundo perfeito, você diria "os dados sempre estarão corretos e eu lembrarei" ... mas quando as pessoas precisam trabalhar em equipe e nem todo mundo está exatamente no seu nível, não é incomum ver ONDE (aa. xx <> '' E bb.zz NÃO É NULL)
Então, em vez de corrigir os membros da minha equipe todos os dias, eu apenas imponho uma regra simples. Sem valores nulos, NUNCA!
Contar valores NON-NULL é mais rápido ... pergunta simples: para que você precisaria fazer isso?
fonte
VARCHAR
coluna precisará de pelo menos 1 byte para armazenar o comprimento da string, mesmo que seja zero.Costumo vê-lo não da perspectiva do banco de dados, mas da perspectiva do programa. Sei que essa pergunta é para o clique do SQL, mas, na verdade, quantos usuários acessam os dados diretamente por mais tempo?
Em um programa eu não gosto de nulo / nada. Existem algumas exceções, mas são exatamente isso. E essas exceções são realmente apenas implementações ruins.
Portanto, se o usuário não inseriu o email, deve haver algo que determine se isso é válido ou não. Se um email em branco estiver bom, ele exibirá uma sequência em branco. Se o usuário não colocou um email e isso viola uma regra, o objeto deve indicar isso.
A idéia de ter significado nulo é antiga e é algo que os programadores modernos precisam resolver.
Mesmo no design do banco de dados, por que o campo de email não pode permitir nulos e ter uma cadeia de comprimento zero e outro campo indicando se o usuário inseriu alguma coisa? É pedir muito um DBMS? O banco de dados não deve, na minha opinião, lidar nem com a lógica de negócios nem com a lógica de exibição. Não foi construído para isso e, portanto, faz um trabalho muito ruim de lidar com isso.
fonte
Eu não acho que isso importe muito, mas eu gosto mais quando o NULL está lá.
Quando visualizo os dados exibidos em uma tabela (como no SQL Server Management Studio), posso distinguir melhor um valor ausente se ele diz NULL e o plano de fundo é de cor diferente.
Se eu vir um espaço em branco, sempre me pergunto se ele está realmente vazio ou se há algum espaço em branco ou caracteres invisíveis. Com NULL, é garantido vazio à primeira vista.
Normalmente, não distingo os valores no aplicativo, porque é inesperado e estranho que NULL e string vazia signifiquem algo diferente. E na maioria das vezes, adotei uma abordagem defensiva e apenas lidei com os dois estados. Mas para mim, como humano, o NULL é mais fácil de processar quando se olha os dados.
fonte