Como um sobrenome Null causa problemas em muitos bancos de dados?

71

Eu li um artigo na BBC. Um dos exemplos que eles disseram foi que as pessoas com o sobrenome 'Null' estão tendo problemas para inserir seus detalhes em alguns sites.

Nenhuma explicação é dada sobre o erro que eles estão enfrentando.

Mas, tanto quanto eu sei, a string 'Null' e o valor Null real são completamente diferentes (do ponto de vista do banco de dados).

Por que isso causaria problemas em um banco de dados?

Nitish
fonte
2
Este é um artigo de blog um tanto famoso sobre suposições que os programadores fazem sobre nomes, escrito por uma das pessoas citadas no artigo da BBC: kalzumeus.com/2010/06/17/…
Jörg W Mittag
12
Xkcd relevante
Reintegra Monica
4
A primeira vez que vi esse cara na TV, presumi que fosse um bug do banco de dados. Então eu descobri que é realmente o nome dele.
Nate Eldredge
3
@JarrodRoberson Como você pode dizer que "toda a premissa é falsa", dada a descrição dos problemas enfrentados por "Jennifer Null" e o mesmo nome no link publicado pelo OP? É um problema real que enfrenta usuários finais reais.
Gort the Robot

Respostas:

102

Não causa problemas no banco de dados. Causa problemas em aplicativos escritos por desenvolvedores que não entendem bancos de dados. A raiz do problema é que muitos softwares relacionados ao banco de dados exibem um registro NULL como a string NULL. Quando um aplicativo confia no formato de seqüência de caracteres de um registro NULL (provavelmente também usando operações de comparação que não diferenciam maiúsculas de minúsculas), esse aplicativo considerará qualquer "null"seqüência de caracteres como NULL. Consequentemente, um nome Nulo seria considerado inexistente por esse aplicativo.

A solução é declarar colunas não nulas como NOT NULLno banco de dados e não aplicar operações de seqüência de caracteres aos registros do banco de dados. A maioria dos idiomas possui excelentes APIs de banco de dados que tornam desnecessárias as interfaces no nível da string. Eles sempre devem ser preferidos, também porque cometem menos erros, como a injeção de SQL.

amon
fonte
30
Nesse caso, no entanto, se você ler o artigo em questão, criar um campo de sobrenome NOT NULLcausará todo um conjunto de problemas para outras pessoas. "Algumas pessoas têm apenas um único nome, não um nome e sobrenome".
MikeTheLiar
41
@Darkhogg muitas pessoas discordam de mim, mas acho que os nomes são como endereços de e-mail - não se preocupe em validá-los, dê ao usuário uma única caixa de texto e deixe-os colocar o que quiserem. Esta é uma informação que, se eu realmente precisar, vou obtê-lo de uma maneira que é certa.
MikeTheLiar
8
@mikeTheLiar Não sei o nome para isso, mas há toda uma classe de erros que surgem ao criar regras excessivamente restritivas aos dados. Frequentemente, você verá códigos postais e números de telefone definidos como numéricos em aplicativos e bancos de dados. Eles não são realmente números porque não faz sentido fazer operações matemáticas neles. Portanto, quando alguém tenta digitar um endereço canadense, fica preso.
JimmyJames
19
@ JimmyJames sim, códigos postais armazenados como numéricos e de repente qualquer pessoa que mora aqui tem um código postal com base 8. "Se você não está fazendo contas com isso, é uma corda, ponto final."
MikeTheLiar
8
@mikeTheLiar. O problema de tratar os nomes como uma única sequência (geralmente preferível, concordo) é quando há um requisito para a classificação alfabética por sobrenome.
TRiG 25/03
13

Para responder sua pergunta específica, existem muitas etapas ao longo da cadeia de eventos entre um formulário da Web e o banco de dados. Se o sobrenome Nullfor erroneamente interpretado como um NULLvalor, o sistema poderá rejeitar um nome perfeitamente válido como inválido. Isso pode acontecer na camada do banco de dados, conforme explicado por amon . Aliás, se esse é um problema específico, o banco de dados provavelmente também está aberto à injeção de SQL, também conhecido como ataque de Tabelas de Bobby . Outra etapa da cadeia que pode estar causando problemas é o processo de serialização .

No geral, o artigo tratava de um problema maior. O mundo é um lugar grande e confuso que nem sempre está de acordo com nossas suposições. Isso é especialmente aparente quando você tenta internacionalizar seu aplicativo. No final do dia , precisamos garantir que nossos aplicativos manejem e codifiquem nossos dados corretamente . Cabe à empresa decidir quantos recursos dedicamos para apoiar casos de borda cada vez mais complicados. Embora eu apóie totalmente a inclusão, entenderei se a empresa decide que "o artista formalmente conhecido como Prince" precisa usar um caractere Unicode para representar seu nome em nosso banco de dados.

Erik
fonte
É difícil imaginar que isso seja causado pelo tipo de interpolação de cadeia não segura que pode levar à injeção de SQL. Se você esquecer de citar a entrada do usuário em uma consulta SQL (por exemplo, INSERT INTO users (first, last) VALUES($first, $last)avaliar INSERT INTO users (first, last) VALUES(Jennifer, Null)) todos aqueles cujos nomes não são palavras-chave válidas ou nomes de colunas SQL apenas lançam erros e também não têm seus registros inseridos. A causa deve ser mais complexa.
Andrew Medico
@AndrewMedico no seu exemplo de homem de palha sim, mas existem muitas maneiras de fazer as coisas erradas. Nunca subestime o poder da <greve> estupidez <\ greve> ignorância. A linha inferior é que não tem idéia de qual é o problema real, porque não podemos rever o código em questão
Erik
7

Bem, antes de ser inserido no banco de dados, é um elemento DOM, uma variável javascript é passada, validada e manipulada, um valor JSON, uma variável na biblioteca JSON de back-end que você está usando e uma variável transmitida, validado e manipulado em sua linguagem de programação de back-end, um elemento de algum tipo de DAO e parte de uma string SQL. Então, para recuperar o valor, você faz tudo ao contrário. Existem muitos lugares para os programadores cometerem erros, e geralmente muitos sem o benefício da digitação estática.

Karl Bielefeldt
fonte
2

Provavelmente é um problema de programação. Se você observar esta resposta aqui sobre como os NULLs estão sendo transmitidos, você poderá facilmente causar algum comportamento indesejado se for "Sr. Null".

https://stackoverflow.com/questions/4620391/mysql-and-php-insert-null-rather-than-empty-string

Você pode ver que se algum elemento de dados fosse passado como NULL, os dados seriam interpolados como um banco de dados nulo no banco de dados.

"NULL"! = Banco de Dados Nulo

Alguns casos de uso e comportamento relacionado ...

Digamos que o sobrenome foi marcado no banco de dados como não nulo; agora, quando os dados são inseridos, eles serão interpretados como um NULL e falharão na inserção.

Outro caso é, digamos que o sobrenome foi anulável no banco de dados. Mr. NULL é inserido e transformado em DBNull.Value, que não é o mesmo que "NULL". Após a inserção, não conseguimos encontrar o Sr. Nulo, porque seu sobrenome não é "NULL", mas, na realidade, um valor nulo no banco de dados.

Então, esses seriam 2 casos de problemas. Como o @Amon salienta, os próprios bancos de dados não têm problemas com nulos, embora se deva entender como os nulos são tratados em cada instância do RDMS, pois haverá diferenças entre diferentes fornecedores.

Jon Raynor
fonte
"Você pode ver que se algum elemento de dados fosse passado como NULL, os dados seriam interpolados como um banco de dados nulo no banco de dados." - a pergunta / resposta aceita do SO vinculada não parece mostrar isso?
MrWhite
2

Eu atribuiria o problema à programação desleixada e ao design deficiente de algumas implementações do SQL. "Nulo" o nome sempre deve ser apresentado e interpretado com aspas. null, o valor do banco de dados, sempre deve ser apresentado sem aspas; mas, ao escrever um código ad-hoc, é fácil adotar o paradigma "qualquer coisa vale a pena" e aceitar as coisas que se acredita serem uma string de forma não citada.

Isso é agravado pelo fato de outros tipos de dados; números, por exemplo, podem e são aceitos de qualquer forma, porque a interpretação é inequívoca.

ddyer
fonte
Você quer dizer implementações ruins de aplicativos usando SQL, com certeza? Nenhuma implementação séria da própria RDBMS seria vulnerável a isso (assim como nenhum aplicativo grave é!)
underscore_d
0

Um problema, fundamentalmente, é que o termo "nulo" é aplicado a dois conceitos diferentes de banco de dados, às vezes usando o contexto para distinguir entre eles:

  1. Algo não tem um valor conhecido
  2. Sabe-se que algo não tem valor

Embora o contexto às vezes seja suficiente para distinguir entre esses conceitos, há momentos em que realmente não. Se alguém estiver usando um registro para armazenar uma consulta de pesquisa, por exemplo, deve haver uma diferença entre dizer "Eu quero alguém com o nome de [qualquer coisa], sem sobrenome", versus "Eu quero alguém cujo primeiro nome seja [ seja qual for], mas cujo sobrenome é desconhecido ". Muitos mecanismos de banco de dados têm um viés em direção a um significado ou outro, mas não são todos iguais. O código que espera que um mecanismo de banco de dados funcione de uma maneira pode funcionar mal se for executado em um mecanismo diferente que seja executado de maneira diferente.

supercat
fonte
Se se sabe que uma sequência não tem valor, o valor deve ser uma sequência vazia, não uma sequência nula.
Byron Jones
0

A maioria das respostas existentes se concentra nas partes não SQL de um aplicativo, mas também pode haver um problema no SQL:

Se instruído a filtrar registros onde o sobrenome de um usuário não está disponível, alguém que não entende muito bem de SQL pode escrever um filtro WHERE u.lastname != 'NULL'. Devido à maneira como o SQL funciona, isso parecerá verificar se u.lastname IS NOT NULL: todos os NULLregistros são filtrados. Todos os não NULLregistros permanecem.

Exceto, é claro, os registros em que u.lastname == 'NULL', mas pode não haver nenhum registro disponível durante o teste.

Isso se tornará mais provável se o SQL for gerado por algum tipo de estrutura, em que essa estrutura não exponha uma maneira facilmente acessível de verificar a não NULLconformidade com os parâmetros, e alguém perceberá "ei, se eu passar a string NULL, faz exatamente o que eu quero! "

hvd
fonte