O que é interessante sobre este tópico de perguntas e respostas é que, na verdade, existem 3 perguntas. Todo mundo respondeu uma pergunta diferente e quase ninguém respondeu à primeira:
- Por que alguns bancos de dados não são normalizados?
- Por que / quando um banco de dados normalizado deve ser desnormalizado ?
- Em que situações é prejudicial ou desnecessário normalizar em primeiro lugar?
Os leitores alertas alertam que essas são perguntas muito diferentes, e tentarei responder cada uma separadamente, evitando muitos detalhes. Por "demais", quero dizer que não creio que este seja o contexto apropriado para levar a cabo um extenso debate sobre os méritos de vários argumentos a favor ou contra a normalização; Vou simplesmente explicar quais são esses argumentos, talvez listar algumas advertências e salvar a filosofia para perguntas mais específicas, se elas surgirem.
Além disso, nesta resposta, estou assumindo que "normalização" implica "BCNF, 3NF ou pelo menos 2NF" , pois esse é o nível de normalização que os designers geralmente pretendem alcançar. É mais raro ver designs de 4NF ou 5NF; embora certamente não sejam objetivos impossíveis, eles se preocupam mais com a semântica dos relacionamentos do que apenas com sua representação , o que requer muito mais conhecimento sobre o domínio.
Então, para frente e para cima:
1. Por que alguns bancos de dados não são normalizados?
A resposta para isso pode ser "porque eles não deveriam ser", mas fazer essa suposição logo de cara é um trabalho de detetive bastante irritado. Não teríamos muito progresso como sociedade se sempre operássemos com a suposição de que o que quer que seja, deveria ser.
Os motivos reais pelos quais os bancos de dados não são normalizados são mais complicados. Aqui estão os 5 principais que eu já me deparei:
Os desenvolvedores que o criaram não sabiam ou não entendiam como normalizar. Uma forte evidência disso vem na forma de muitas outras opções ruins de design, como usar colunas varchar para tudo ou ter uma bagunça espaguete de nomes de tabelas e colunas sem sentido . E garanto que vi bancos de dados "reais" tão ruins quanto os dos artigos do TDWTF.
Os desenvolvedores que o criaram não se importavam ou eram ativamente contra a normalização em princípio . Note, aqui não estou falando de casos em que uma decisão deliberada foi tomada para não normalizar com base em análise contextual, mas equipes ou empresas em que a normalização é mais ou menos compreendida, mas simplesmente ignorada ou evitada por hábito. Mais uma vez, surpreendentemente comum.
O software é / foi feito como um projeto Brownfield . Muitos puristas ignoram esse negócio perfeitamente legítimo , e não o motivo técnico para não normalizar. Às vezes, na verdade, você não consegue projetar um novo banco de dados do zero, precisa seguir um esquema herdado existente, e tentar normalizar nesse ponto envolveria muita dor. O 3NF não foi inventado até 1971, e alguns sistemas - especialmente sistemas financeiros / contábeis - têm suas raízes ainda mais longe do que isso!
O banco de dados foi originalmente normalizado , mas um acúmulo de pequenas alterações por um longo período de tempo e / ou uma equipe amplamente distribuída introduziu formas sutis de duplicação e outras violações de qualquer forma normal que estivesse originalmente em vigor. Em outras palavras, a perda da normalização foi acidental e pouco tempo foi gasto na refatoração.
Foi tomada uma decisão comercial deliberada de não gastar tempo com análise de negócios ou design de banco de dados e apenas "concluí-lo". Isso geralmente é uma economia falsa e acaba se tornando uma forma crescente de dívida técnica , mas às vezes é uma decisão racional, pelo menos com base em informações conhecidas na época - por exemplo, o banco de dados pode ter sido concebido como um protótipo, mas acabou sendo sendo promovido ao uso da produção devido a restrições de tempo ou mudanças no ambiente de negócios.
2. Por que / quando um banco de dados normalizado deve ser desnormalizado?
Essa discussão geralmente surge quando um banco de dados é normalizado para começar. O desempenho é ruim ou há muita duplicação nas consultas (junções), e a equipe sente, com ou sem razão, que foi o mais longe possível com o design atual. É importante observar que a normalização melhora o desempenho na maioria das vezes, e existem várias opções para eliminar junções em excesso quando a normalização parece estar funcionando contra você, muitas das quais são menos invasivas e arriscadas do que simplesmente mudar para um modelo desnormalizado:
Crie visualizações indexadas que encapsulem as áreas problemáticas mais comuns. DBMSes modernos são capazes de torná-los inseríveis ou atualizáveis (por exemplo, INSTEAD OF
gatilhos do SQL Server ). Isso tem um pequeno custo para as instruções DML nas tabelas / índices subjacentes, mas geralmente é a primeira opção que você deve tentar, porque é quase impossível estragar tudo e custa quase nada para manter. Obviamente, nem todas as consultas podem ser transformadas em uma exibição indexada - as consultas agregadas são as mais problemáticas. O que nos leva ao próximo item ...
Crie tabelas agregadas desnormalizadas que são atualizadas automaticamente por gatilhos. Essas tabelas existem além das tabelas normalizadas e formam um tipo de modelo CQRS . Outro modelo do CQRS, mais popular atualmente, é usar pub / sub para atualizar os modelos de consulta, o que oferece o benefício da assincronia, embora isso possa não ser adequado em casos muito raros em que os dados não possam ficar obsoletos.
Às vezes, as exibições indexadas não são possíveis, as taxas de transação e os volumes de dados são altos demais para admitir acionadores com desempenho aceitável, e as consultas sempre devem retornar dados em tempo real. Essas situações são raras - eu arriscaria adivinhar que elas podem se aplicar a coisas como comércio de alta frequência ou bancos de dados de aplicação da lei / inteligência - mas elas podem existir. Nesses casos, você realmente não tem opção a não ser desnormalizar as tabelas originais.
3. Em que situações é prejudicial ou desnecessário normalizar em primeiro lugar?
De fato, existem vários bons exemplos aqui:
Se o banco de dados estiver sendo usado apenas para relatórios / análises. Normalmente, isso implica que há um banco de dados normalizado adicional sendo usado para OLTP, que é periodicamente sincronizado com o banco de dados de análise por meio de ETL ou sistema de mensagens.
Ao impor um modelo normalizado, é necessária uma análise desnecessariamente complexa dos dados recebidos. Um exemplo disso é que pode ser um sistema que precisa armazenar números de telefone coletados de vários sistemas ou bancos de dados externos. Você pode desnormalizar o código de chamada e o código de área, mas é necessário considerar todos os diferentes formatos possíveis, números de telefone inválidos, números pessoais (1-800-GET-STUFF), sem mencionar diferentes localidades. Geralmente, é mais problemático do que vale a pena, e os números de telefone geralmente são empurrados para um único campo, a menos que você tenha uma necessidade comercial específica do código de área por conta própria.
Quando o banco de dados relacional está principalmente lá para fornecer suporte transacional para um banco de dados não relacional adicional. Por exemplo, você pode estar usando o banco de dados relacional como uma fila de mensagens ou para rastrear o status de uma transação ou saga, quando os dados primários estiverem sendo armazenados no Redis ou MongoDB ou o que seja. Em outras palavras, os dados são "dados de controle". Normalmente, não há sentido em normalizar dados que não são realmente dados comerciais .
Arquiteturas orientadas a serviços que compartilham um banco de dados físico. Este é um pouco de um estranho, mas em um verdadeiro SOA, você vai ocasionalmente precisa ter dados fisicamente duplicados porque os serviços não estão autorizados a diretamente consulta de dados de cada um. Se eles acontecem estar compartilhando o mesmo banco de dados físico, os dados vão aparecer para não ser normalizada - mas geralmente, os dados de propriedade de cada serviço individual está ainda normalizado menos um dos outros fatores atenuantes está no lugar. Por exemplo, um serviço de cobrança pode ser o proprietário da entidade de cobrança, mas o serviço de contabilidade precisa receber e armazenar a data e o valor da cobrança para incluí-la na receita daquele ano.
Tenho certeza de que há mais motivos que eu não listei; o que estou dizendo, em essência, é que eles são bem específicos e serão bastante óbvios quando surgirem na prática. Os bancos de dados OLAP devem usar esquemas em estrela, os SOAs devem ter alguma duplicação etc. Se você estiver trabalhando com um modelo de arquitetura conhecido que simplesmente não funciona com a normalização, não será normalizado; de um modo geral, o modelo de arquitetura tem precedência sobre o modelo de dados.
E para responder à última pergunta:
É verdade que bons arquitetos e especialistas escolhem um design desnormalizado, enquanto desenvolvedores não experientes escolhem o oposto? Quais são os argumentos contra iniciar seu design com a normalização em mente?
Não, isso é completo e absoluto BS É também BS que os especialistas sempre escolhem um design normalizado . Os especialistas não seguem apenas um mantra. Eles pesquisam, analisam, discutem, esclarecem e repetem, e então escolhem qualquer abordagem que faça mais sentido para sua situação específica.
O banco de dados 3NF ou BCNF geralmente é um bom ponto de partida para a análise, porque foi testado e comprovado com sucesso em dezenas de milhares de projetos em todo o mundo, mas também o C. também não significa que usamos automaticamente o C em todos os novo projeto. Situações do mundo real podem exigir algumas modificações no modelo ou o uso de um modelo completamente diferente. Você não sabe até que você esteja em tal situação.