Imagine um formulário da web com um conjunto de caixas de seleção (qualquer uma ou todas elas podem ser selecionadas). Eu escolhi salvá-los em uma lista separada por vírgula de valores armazenados em uma coluna da tabela do banco de dados.
Agora, eu sei que a solução correta seria criar uma segunda tabela e normalizar adequadamente o banco de dados. Foi mais rápido implementar a solução fácil, e eu queria ter uma prova de conceito desse aplicativo rapidamente e sem ter que gastar muito tempo nele.
Eu pensei que o tempo economizado e o código mais simples valiam a pena na minha situação, isso é uma opção de design defensável ou deveria ter normalizado desde o início?
Um pouco mais de contexto, este é um pequeno aplicativo interno que substitui essencialmente um arquivo do Excel que foi armazenado em uma pasta compartilhada. Também estou perguntando, porque estou pensando em limpar o programa e torná-lo mais sustentável. Há algumas coisas lá em que não estou totalmente feliz, uma delas é o tópico desta pergunta.
fonte
Respostas:
Além de violar a Primeira forma normal por causa do grupo de valores repetidos armazenados em uma única coluna, as listas separadas por vírgula têm muitos outros problemas mais práticos:
idlist REGEXP '[[:<:]]2[[:>:]]'
*Para resolver esses problemas, você precisa escrever toneladas de código de aplicativo, reinventando a funcionalidade que o RDBMS já fornece com muito mais eficiência .
As listas separadas por vírgula estão erradas o suficiente para tornar este o primeiro capítulo do meu livro: Antipatterns SQL: Evitando as Armadilhas da Programação de Banco de Dados .
Há momentos em que você precisa empregar desnormalização, mas, como o @OMG Ponies menciona , esses são casos de exceção. Qualquer “otimização” não relacional beneficia um tipo de consulta em detrimento de outros usos dos dados; portanto, saiba quais das suas consultas precisam ser tratadas de modo que elas mereçam desnormalização.
* O MySQL 8.0 não suporta mais esta sintaxe de expressão de limite de palavras.
fonte
"Um dos motivos foi a preguiça".
Isso soa um alarme. A única razão pela qual você deve fazer algo assim é que você sabe como fazê-lo "da maneira certa", mas chegou à conclusão de que há uma razão tangível para não fazê-lo dessa maneira.
Dito isto: se os dados que você optar por armazenar dessa maneira forem aqueles que você nunca precisará consultar, pode haver um motivo para armazená-los da maneira que você escolheu.
(Alguns usuários contestariam a afirmação no meu parágrafo anterior, dizendo que "você nunca pode saber quais requisitos serão adicionados no futuro". Esses usuários estão equivocados ou afirmam uma convicção religiosa. Às vezes é vantajoso trabalhar com os requisitos que você tem antes de você.)
fonte
Existem inúmeras perguntas sobre o SO perguntando:
Outro problema com a lista separada por vírgula é garantir que os valores sejam consistentes - armazenar texto significa a possibilidade de erros de digitação ...
Todos esses são sintomas de dados não-normalizados e destacam por que você deve sempre modelar para dados normalizados. A desnormalização pode ser uma otimização de consulta, a ser aplicada quando a necessidade realmente se apresentar .
fonte
Em geral, qualquer coisa pode ser defensável se atender aos requisitos do seu projeto. Isso não significa que as pessoas vão concordar ou querer defender sua decisão ...
Em geral, armazenar dados dessa maneira é subótimo (por exemplo, mais difícil de realizar consultas eficientes) e pode causar problemas de manutenção se você modificar os itens em seu formulário. Talvez você possa ter encontrado um meio termo e usado um número inteiro representando um conjunto de sinalizadores de bits?
fonte
Sim, eu diria que é realmente tão ruim assim. É uma escolha defensável, mas isso não a torna correta ou boa.
Quebra a primeira forma normal.
Uma segunda crítica é que colocar resultados brutos diretamente em um banco de dados, sem nenhuma validação ou vinculação, deixa você aberto a ataques de injeção de SQL.
O que você chama de preguiça e falta de conhecimento de SQL é o material de que os neófitos são feitos. Eu recomendo reservar um tempo para fazê-lo corretamente e encará-lo como uma oportunidade de aprender.
Ou deixe como está e aprenda a dolorosa lição de um ataque de injeção de SQL.
fonte
Bem, eu tenho usado uma lista separada por tabulação par de chave / valor em uma coluna NTEXT no SQL Server há mais de 4 anos e funciona. Você perde a flexibilidade de fazer consultas, mas por outro lado, se você tem uma biblioteca que persiste / derpersista no par de valores-chave, não é uma má ideia.
fonte
Eu precisava de uma coluna de vários valores, que poderia ser implementada como um campo xml
Pode ser convertido em uma vírgula delimitada conforme necessário
consultando uma lista XML no servidor sql usando o Xquery .
Por ser um campo xml, algumas das preocupações podem ser tratadas.
Com CSV: não é possível garantir que cada valor seja o tipo de dados correto: não há como impedir 1,2,3, banana, 5
Com XML: os valores em uma tag podem ser forçados a serem do tipo correto
Com CSV: não é possível usar restrições de chave estrangeira para vincular valores a uma tabela de pesquisa; nenhuma maneira de impor integridade referencial.
Com XML: ainda é um problema
Com CSV: não é possível impor exclusividade: não há como impedir 1,2,3,3,3,5
Com XML: ainda é um problema
Com CSV: não é possível excluir um valor da lista sem buscar a lista inteira.
Com XML: itens únicos podem ser removidos
Com CSV: difícil pesquisar todas as entidades com um determinado valor na lista; você precisa usar uma varredura de tabela ineficiente.
Com XML: o campo xml pode ser indexado
Com CSV: difícil de contar elementos na lista ou fazer outras consultas agregadas. **
Com XML: não particularmente difícil
Com CSV: difícil associar os valores à tabela de pesquisa que eles fazem referência. **
Com XML: não particularmente difícil
Com CSV: difícil obter a lista em ordem classificada.
Com XML: não particularmente difícil
Com CSV: armazenamento de números inteiros como seqüências de caracteres ocupa aproximadamente o dobro do espaço que o armazenamento de números inteiros binários.
Com XML: o armazenamento é ainda pior que um CSV
Com CSV: além de muitos caracteres de vírgula.
Com XML: tags são usadas em vez de vírgulas
Em resumo, o uso de XML contorna alguns dos problemas da lista delimitada E pode ser convertido em uma lista delimitada conforme necessário
fonte
Sim, isso é ruim. Minha opinião é que, se você não gosta de usar bancos de dados relacionais, procure uma alternativa que melhor lhe convém, há muitos projetos interessantes "NOSQL" por aí com alguns recursos realmente avançados.
fonte
Eu provavelmente tomaria o meio termo: transforme cada campo no CSV em uma coluna separada no banco de dados, mas não se preocupe muito com a normalização (pelo menos por enquanto). Em algum momento, a normalização pode se tornar interessante, mas com todos os dados inseridos em uma única coluna, você praticamente não obtém nenhum benefício ao usar um banco de dados. Você precisa separar os dados em campos lógicos / colunas / como quiser chamá-los antes de poder manipulá-los de maneira significativa.
fonte
Se você tiver um número fixo de campos booleanos, poderá usar um
INT(1) NOT NULL
(ou,BIT NOT NULL
se existir) ouCHAR (0)
(nulo) para cada um. Você também pode usar umSET
(eu esqueço a sintaxe exata).fonte
INT(1)
leva 4 bytes; o(1)
não tem sentido.