Razão para não usar número anulável no Oracle?


12

Nossa empresa está fazendo interface com outra empresa de software para um projeto conjunto, e fomos informados de que, se um determinado valor não for exibido, devemos passar um -5000 (seu valor arbitrário de sentinela); o motivo é que nenhuma coluna numérica no banco de dados Oracle suporta valores nulos, por recomendação de seu (agora anterior) desenvolvedor Oracle. Essa empresa também grava a grande maioria de seu código no VB6 (transição lenta para o VB.NET, que é outro tópico por outro dia ...). Por pura curiosidade, existe algum motivo válido para esta recomendação? Não consigo pensar em ninguém do meu lado.

--- editar

Obrigado pelo feedback de todos. Fiz a mesma pergunta no CodeProject.com ( link ) e recebi comentários muito semelhantes. Parece que o único momento em que alguém poderia começar a justificar essa prática está relacionado a chaves estrangeiras, e posso afirmar que eles não usam chaves estrangeiras em nenhum lugar do sistema. O desenvolvedor que fez essa determinação (eu trabalhava naquela empresa) tem muito mais experiência do que eu, então queria ter certeza de que não havia uma razão válida para isso antes que a zombaria se seguisse.


2
Quer dizer, diferente de "é isso que a API especifica"?
Robert Harvey

Sim, estou mais curioso sobre por que a API deles especificaria isso em primeiro lugar; existe uma razão para essa prática ou isso é apenas uma loucura?

3
Loucura da mais alta ordem!
Philᵀᴹ

Respostas:


17

Realisticamente, o requisito é louco. Como todas as grandes idéias malucas, no entanto, é provavelmente baseado em uma pepita de razoabilidade potencial tirada muito do contexto por pessoas que não entendem a lógica subjacente.

Pode ser razoável projetar um esquema de banco de dados de forma que nenhum NULLvalor seja permitido. Se você fizer isso, no entanto, estará comprometendo-se com um nível de normalização em que todos os elementos não necessários serão divididos em uma tabela separada com uma referência de chave estrangeira apropriada para o pai. Geralmente, isso não é feito na prática, mas nos casos em que faz sentido, pode haver benefícios.

Se você deseja projetar um esquema de banco de dados de modo que nenhum NULLvalor seja permitido, não faz sentido permitir muito menos exigir valores mágicos para indicar que algo é desconhecido. Isso introduz todos os problemas que a permissão de NULLvalores possui, além de adicionar código adicional para verificar os valores mágicos que precisam ser repetidos em todo o lugar. Não faz sentido desenvolver uma API que exija que valores mágicos sejam transmitidos, independentemente do design do banco de dados - se você quiser prejudicar seu código com verificações de valores mágicos, realmente não deve permitir que essa loucura se propague para outros sistemas .


O +1 e o código adicional para verificar os valores mágicos não podem usar funções conhecidas, como, COALESCE()por isso, fica ainda mais complicado.
precisa saber é o seguinte

E os valores precisam ser armazenados em qualquer índice nessa coluna. Os índices não precisam armazenar valores nulos.
Tripp Kinetics

15

Não há motivo válido para usar um valor mágico em vez de NULL. Este pode ser o processo de pensamento de alguém criando essa bagunça. Eles escrevem algo assim:

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

Quando isso não retorna os resultados esperados, eles percebem que não inclui NULLs e precisariam escrever isso:

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

Eles não querem escrever ou esquecer no futuro para escrever isso, então eles têm a solução de criar todos os NULLS -5000. Magicamente, sua consulta original lida com NULLs sem nenhuma alteração. O que eles não percebem é que agora alguém que deseja excluir esses valores precisa escrever o seguinte:

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

Ou se eles quisessem esses valores e estivessem pesquisando um intervalo mais alto:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

Eles também podem não perceber que o seguinte não seria mais significativo:

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

Em vez disso, uma pessoa precisa se lembrar do valor mágico. Com cada tipo de dados usado, eles precisam se lembrar de mais valores mágicos, por exemplo, 1/1 // 1900, "Z", -5000. Além disso, quando o valor mágico está nos dados, eles também devem se lembrar de valores mágicos alternativos.

Portanto, para um caso específico, ele simplifica o código às custas de outros casos, sem mencionar o espaço em disco, o tamanho do índice, a análise de consultas, a consistência etc.


8

É loucura total e não há justificativa para isso. NULLfoi criado para representar a ausência de um valor e usar um valor real como -5000 is bonkers.

Normalmente, eu não escreveria uma resposta tão curta, mas a pergunta merece ser uma das mais visíveis no dba.se e quanto mais respostas, melhor.


5

Pensei nisso um pouco tentando ser positivo e justificar a necessidade de usar um valor arbitrário em vez de um nulo e parece (pelo menos para mim) não haver uma razão válida para isso, exceto talvez em um conjunto de dados fechado de mineração de dados para melhorar e simplificar o desempenho e as consultas, e somente nos casos em que os números não são valores que podem distorcer os dados. Mesmo isso teria que ser considerado com cuidado. Em todas as situações do mundo real, dar valor a nulo não é uma boa prática. Isso transforma uma definição de coluna NOT NULL do seu amigo para o inimigo, uma vez que realmente não é verdade.

É uma coisa muito diferente dizer que nosso aplicativo não deve aceitar um valor NULL para algumas (ou mesmo todas) colunas. Isso é sensato e é uma boa prática e há benefícios bem documentados em não permitir nulos (chaves e índices e cálculos estatísticos, por exemplo). No entanto, atribuir um valor a "sentar no lugar" de um nulo não é o mesmo. É o caminho certo para você, já que você precisa primeiro selecionar um valor que nunca será usado, filtrar esse valor como seria o nulo e lembre-se de não usá-lo em cálculos e resumos e removê-lo dos feeds de dados externos . Isso é pelo menos tão ruim quanto usar um nulo para representar um valor real, que é o que você diz a si mesmo que está evitando, mas não está.

A maioria dos problemas que os nulos causam, uma vez entendidos, pode ser tratada (melhor normalização, índices baseados em funções ou bitmap ou com um simples WHERE x IS NOT NULL). Você acha que em alguma empresa de telecomunicações de grande porte ou na Amazon na reunião mensal de desempenho, algum DBA está delineando esse grande plano para acelerar um pouco as consultas em seus enormes conjuntos de dados "substituindo null por um valor arbitrário, algo como -5000 ou algo assim - Estou aberto ao valor ... ". Ou você acha que eles gastam seu tempo dividido entre um melhor design de aplicativo para filtrar nulos indesejados e otimizar a consulta com base nos dados reais que recebem ? Tudo bem, talvez uma reunião mensal seja um pouco otimista, mas sempre que isso acontece, posso garantir que "Substituir nulos por -5000 (ou o que for) para uma API melhor" não é um item da agenda.

Para mim, é bom dizer que não aceitarei dados ausentes (você deve ter uma idade, preço ou código de região ou qualquer outra coisa) e, às vezes, é bom dizer que para esta coluna há um valor padrão que será inserido se você não coloca outra coisa. Não é bom reservar um valor para significar nulo. Pense nos campos de nome do meio como um exemplo. Às vezes, elas não existem, pois os pais têm preguiça de preencher todas as caixas. Adicionamos "nenhum" ou "ausente" ou "desconhecido" aos nossos dados para melhorar nossas pesquisas? Não, porque pode haver pessoas estranhas que mudam seus nomes para esses valores e, portanto, quando imprimimos os dados, não sabemos se devemos incluí-los ou não. É um exemplo simples, mas abrangente. Conhecemos o NULL e temos funções integradas previsíveis para lidar com isso. Você não pode codificar isso melhor.

Se nenhuma resposta (ou NULL) não for uma resposta válida para sua solicitação de entrada, não permita isso no aplicativo ou no banco de dados; se for uma boa resposta, você deverá permitir tanto no aplicativo quanto no banco de dados e lidar com como uma resposta válida. Se fizer parte de um conjunto de respostas válidas, seu banco de dados deverá ser projetado para armazená-lo. Afinal, você não diz ei, os campos numéricos são tão chatos que permitem armazenar números em blobs e usar imagens de animais selvagens para representar cada número, porque isso é loucura (legal, mas louca). Também não decidimos que não gostamos da letra B e, como um pesadelo cruel da Vila Sésamo, a substituímos por um # em nossos dados. Se B não for uma resposta, queremos que digamos ao usuário "Ei, você não pode colocar um B aqui". Então, por que tratar nulo de maneira diferente?

Portanto, evite os nulos que você não deseja no nível do aplicativo e lide com eles no banco de dados, onde você os aceita de outra forma tão certo quanto girafa + girafa = hipopótamo, sua inútil discussão de dados causará problemas.


2
Meus pais não eram preguiçosos e, a propósito, não tenho nome do meio. Nem todas as pessoas vivem nos EUA.
precisa saber é o seguinte

1
Era para ser um exemplo alegre, sem ofensa. Obviamente, existem muitas pessoas sem nomes do meio (o primeiro ponto) por muitas razões bastante válidas (o ponto principal). O valor nulo nesta coluna não diz nada sobre o motivo da falta. Não tenho certeza do seu ângulo geopolítico - eu não moro nos EUA, mas na verdade tenho um nome do meio. É difícil fazer suposições com base na falta de dados, eu acho.

Nenhuma ofensa tomada. Na verdade, votei na sua resposta. Eu acho que você acertou em cheio com o seu ponto principal de que existe uma diferença entre não aceitar / permitir Nulls no banco de dados e substituir Nulls por um valor mágico.
precisa saber é o seguinte

5
Eu adoraria se meu nome do meio fosse "-5000"! : D
Philᵀᴹ
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.