Como estudante de CS, aprendi um número decente de linguagens de programação ao longo dos anos, a maioria das quais teve algum conceito de tipo "anulável" ou "opcional". Note que estou não falar de ponteiros nulos ou referências, ou linguagens fracamente tipadas como JavaScript, onde tudo pode ser null
. Exemplos do que estou falando incluem boost::optional
(C ++), java.util.Optional
(Java 8.0), prelude.Maybe
(Haskell) e todos os '?' tipos (por exemplo int?
, float?
C # e Kotlin). Essas são construções que adicionam capacidade de anulação a um tipo anteriormente não anulável em um sistema de tipo estático estrito.
O SQL tem um conceito semelhante: um tipo como INTEGER
pode ser anulável ou não anulável - mas há uma diferença. No SQL, INTEGER
é anulável por padrão e deve ser explicitamente gravada como INTEGER NOT NULL
para não ser anulável.
Parece-me extremamente contra-intuitivo e potencialmente perigoso por permitir que o NULL seja o comportamento padrão. Obviamente, o SQL existe há tanto tempo neste ponto que (a maioria) os desenvolvedores de SQL desenvolveram uma percepção saudável das armadilhas do NULL. Mas não posso deixar de imaginar que, nos primeiros dias, os NULL costumavam aparecer em lugares inesperados e problemáticos.
O SQL antecede todos os exemplos que forneci, portanto, é possível que isso seja apenas uma questão de evolução histórica. Ainda assim, devo perguntar, existe alguma boa razão para o idioma ser projetado dessa maneira, com tipos sendo anuláveis por padrão?
Em caso afirmativo, é apenas uma razão histórica ou a lógica é válida para o design de banco de dados hoje?
Edit: Não estou perguntando por que NULL faz parte do SQL ou por que colunas anuláveis são úteis. Estou apenas perguntando por que a coluna é anulável por padrão . Por exemplo, por que escrevemos:
column1 FLOAT,
column2 FLOAT NOT NULL
Ao invés de:
column1 FLOAT NULLABLE,
column2 FLOAT
fonte
Respostas:
Na Uni fui ensinado que o oposto é verdadeiro. É muito mais perigoso fazer algo
not null
sem razão. Com um campo anulável, a pior coisa que pode acontecer é você tropeçar no aplicativo que acessa os dados. Oh querida, volte e corrija o aplicativo ...Com um campo não nulo, você torna impossível adicionar registro porque algum campo arbitrário não está disponível. Agora você precisa alterar o modelo de dados e potencialmente corrigir o resultado em vários lugares diferentes ...
É bom pensar
null
em "desconhecido". Se houver algum motivo plausível para você inserir um registro sem saber algo, ele deverá ser anulado.Um dos meus professores da universidade descreveu assim:
Na prática, reserve os
not null
campos necessários para entender o registro. Por exemplo:Uma tabela de locais com campos (ID, nome do local, país, longitude, latitude) ... "longitude" "latitude" deve ser anulável para que você possa armazenar a existência de um local antes de saber onde ele está.
Mas se você tiver uma tabela cujo único objetivo é armazenar coordenadas geográficas com campos (Item_id, longitude, latitude), todo o registro não terá sentido se a longitude e a latitude forem nulas. Portanto, nesse caso, eles devem ser não nulos
Na minha experiência profissional desde a uni, há muito mais campos que podem ser opcionais do que precisam ser obrigatórios.
fonte
Intuitivo está nos olhos de quem vê e sua opinião é moldada pelas coisas a que você foi exposto. Sou de uma época em que esse tipo de segurança não era padrão e as ferramentas não apontavam quando você brincava. Estou usando a motosserra sem uma proteção de lâmina há tempo suficiente para que meu primeiro instinto seja evitar completamente a intuição, voltar ao DDL e descobrir exatamente quais suposições o esquema me permitirá fazer sobre seus dados.
Eu acho que você está exagerando os perigos relativos.
NOT NULL
tem seu próprio conjunto de armadilhas que podem levar a erros igualmente insidiosos. (Enumerá-los seria forragem para uma pergunta diferente.)O designer de uma tabela sempre tem a opção de restringir uma coluna
NULL
ouNOT NULL
e fará uma ou outra para contornar o padrão, seja ele qual for. Não restringir uma coluna corretamente é uma falha do desenvolvedor em seguir as regras de negócios. Não fazer a coisa certa em outro lugar, com base na definição da coluna, é a falha do desenvolvedor em entender os dados que estão sendo entregues. Também não há correção técnica.Não, não existe. Como ambos apresentam riscos, também não há uma boa razão para o idioma ser projetado de outra maneira. Tudo se resume a escolher o seu veneno.
fonte
As colunas anuláveis são necessárias no SQL devido a junções externas (também conhecidas como junções à esquerda ou junções à direita). Quando a linha de um lado da junção não possui correspondência do outro lado, os campos do outro lado devem ter NULLs. Como a saída de uma junção pode ter colunas anuláveis, as tabelas base também devem suportá-las devido ao princípio do fechamento relacional (que basicamente declara que o resultado de uma consulta ou exibição deve ser indistinguível de uma tabela base).
Diante disso, o SQL deve suportar colunas anuláveis. Por outro lado, colunas não anuláveis são um recurso secundário - o SQL ainda pode funcionar sem elas.
fonte
Vamos virar e dizer que você está certo. Digamos que seu número inteiro não seja nulo por padrão.
O que significa que ele deve ter um valor por padrão. Mesmo quando não se sabe.
Portanto, quando você atualiza a tabela de pessoas e tem duas opções: É impossível atualizar a tabela porque você não inseriu peso. Ou quando você não forneceu o argumento de peso, ele colocou no padrão "-1 quilos" quando desconhecido.
Ambas as situações são indesejáveis. Você deseja adicionar clientes, mesmo que não saiba o peso deles. Mas também, você não deseja ter valores "proxy". Valores que são espaços reservados, mas que podem ter um significado real, por exemplo: podem ser usados em funções matemáticas como "média", mas não são valores reais.
Quero dizer, ao calcular um peso médio, -1 é um valor válido na sua função média matemática, mas não como o peso das pessoas. Você usa null e agora sua função média sabe ignorar esse valor.
Além disso, eu realmente não compararia o SQL às linguagens de programação ao discutir nulos, eles são inerentemente diferentes, o nulo no SQL faz parte da teoria do design de banco de dados relacional.
fonte
Não. Não existe um motivo convincente para o SQL usar como padrão nulo. De fato, muitos pesquisadores proeminentes na teoria de bancos de dados relacionais discordaram dessa decisão de design, talvez mais notavelmente Chris Date , um colaborador frequente do criador original do banco de dados relacional, Edgar Codd . Date (junto com o co-autor Hugh Darwen) publicou um livro bem conhecido sobre teoria relacional (" O Terceiro Manifesto ") que descreve princípios para projetos alternativos para uma família de idiomas relacionais que eles chamam de "D", juntamente com um exemplo chamado " Tutorial D ".
Linguagens D são proibidas explicitamente de suportar valores NULL ("D não incluirá nenhum conceito de uma" relação "na qual alguma" tupla "inclua algum" atributo "que não tenha um valor."). Em vez disso, os valores opcionais são suportados por tipos de dados alternativos que incluem marcadores "não presentes" ou valores semelhantes. As linguagens D fornecem um modelo rico para tipos definidos pelo usuário que permitem que qualquer tipo nativo seja estendido com esses valores extras.
Existem razões teóricas convincentes para que essa seja uma boa ideia, e Date & Darwen escreveram muito sobre isso, bem como outras decisões que tomaram em seu design. Eu recomendo ler o trabalho deles sobre esse tópico.
fonte
Representing x with null is a bad idea
não infere issoallowing x by default is bad
. Ergo isso não implica queallowing null by default is bad where null is the only available representation of x
Not Present = Not Present
onde em SQL nemnull = null
ounull != null
são verdadeiras.Não discordo de sua premissa sobre qual deve ser o padrão, mas é uma boa prática não assumir nada como desenvolvedor. Verificar as especificações em uma tabela de banco de dados não deve ser muito difícil.
Mais do ponto de vista do DBA, no qual você seria solicitado a carregar dados em massa, especialmente ao mesclar a partir de outros sistemas, é melhor conhecer a configuração de cada campo, se você tem dados para inserir ou não.
Negócios e aplicativos são administrados por pessoas. Se eles não são programadores, a definição de "nunca" e "sempre" não é exatamente a mesma e mudará com o tempo. A configuração nula atual em um determinado campo não deve ser confusa.
fonte
Bancos de dados são bestas diferentes das linguagens de programação normais.
Como o esquema de uma tabela é definido, todos os dados precisam estar presentes ao salvar as informações em uma linha. No entanto, muitos desses dados podem não ser necessários para criar uma representação válida de um objeto de modelo, uma vez carregado no seu código. Exigir que todos os dados sejam não nulos e preenchidos significará que esses campos não obrigatórios deverão conter um valor e, ainda assim, ainda não possuem um, eles são "desconhecidos".
Imagine ter que preencher TODOS os campos nos formulários da Web o tempo todo, já que eles não podem ser nulos no banco de dados, eles devem receber um valor ... uma receita de insanidade!
Você pode definir alguns valores reservados para representar a ausência de dados, uma sequência vazia, um número específico, uma data específica etc., dependendo do tipo de dados, mas que valor escolher? Então você precisa garantir que todos concordem que esses valores arbitrários realmente significam "desconhecido" e não "1º de janeiro de 1970", por exemplo. A aversão nula pode assumir várias formas e levá-lo a desvios longos e complicados, apenas porque alguém disse que os nulos eram ruins. Quão complexo você está pronto para ficar apenas para evitar lidar com nulos?
Tendo um único valor universal para tudo o que é desconhecido, acho muito preferível do que usar algum conjunto de valores constantes arbitrários. Não estou dizendo que valores constantes são ruins e nulo é melhor, se seu modelo é bem servido por uma constante para representar essas informações, use-o de qualquer maneira, mas existem muitas situações em que um nulo é exatamente o que melhor se encaixa. Para todos os haters nulos, esta é uma situação se nulo foi negado, teria que ser inventado!
Vendo quão difundido é o conceito de "desconhecido" em um banco de dados, sim, eu diria que tornar os valores nulos um padrão faz muito sentido.
Aprofundando e analisando outras respostas aqui, não ficaria surpreso ao saber que os nulos não são apenas um "recurso de linguagem", mas uma parte integrante da teoria subjacente na qual o SQL se baseia. Pode-se remover C (a velocidade da luz) da relatividade, mas o conceito de velocidade máxima absoluta permanece e ainda deve ser expresso, para que volte de alguma forma ou forma.
fonte
Resposta curta: compatibilidade com versões anteriores.
Resposta longa:
Em um banco de dados totalmente normalizado, NULL não é permitido em nenhuma coluna. Por exemplo, suponha que exista uma tabela chamada MailingAddress que tenha uma coluna PostOfficeBox, que é um número inteiro. Como nem todo mundo tem uma caixa postal, existem duas maneiras de implementar isso.
Primeiro, NULL pode ser permitido na coluna.
Segundo, PostOfficeBox é removido do MailingAddress e uma nova tabela, PostOfficeBox é criada com uma coluna Number e seu PK sendo o FK para MailingAddress. Mas agora são necessárias duas consultas para obter endereços para correspondência: uma para quem não tem caixas postais e outra para quem tem.
O SQL permite NULLs em colunas para propósitos práticos.
fonte