E-Zine Exclusivo para o Whastapp

Quando é interessante desnormalizar o banco de dados?

database Quando é interessante desnormalizar o banco de dados?
foto_ramos Quando é interessante desnormalizar o banco de dados?

Ramos de Souza Janones

Janones, é um empreendedor brasileiro apaixonado por empreendedorismo e tecnologia. Ao longo dos anos trabalhando com o desenvolvimento de softwares desktop desde a linguagem Clipper, passando pelo Delphi e atualmente com Java.

Optou pela formação de Publicidade e Marketing por sua segunda empresa de tecnologia ter participado do "boom" da internet nos anos 90 e na procura de melhorar seus conhecimentos em negócios.

Em razão da principal formação e profundos conhecimentos em programação e banco de dados, é capaz de realizar o desenvolvimento de aplicativos web, desktop e mobile com maior criatividade e inovação que profissionais de desenvolvimento com uma formação única e mais especifica, dedicada somente ao desenvolvimento de softwares.

Com toda sua experiência com empresas de software, sua formação e paixão por negócios escreveu o livro "Marketing para Empresas e Profissionais de Software", publicado pela editora carioca Ciência Moderna em 2012. Além de outros livros sobre programação.
foto_ramos Quando é interessante desnormalizar o banco de dados?

Primeiro vamos entender que desnormalizar não é a mesma coisa que não normalizar. Desnormalizar é um processo consciente com um objetivo claro. Um banco de dados bem normalizado costuma ser mais rápido que um banco de dados não normalizado. Cada forma normal é mais extrema que a outra. Reduzir de uma forma normal para outra seria desnormalizar? Ou seria apenas reduzir a normalização? Não sei.

Uma das maiores vantagens da normalização é facilitar a integridade de dados eliminando a redundância. Desnormalização precisa ser feita com muito cuidado.

A normalização se aplica bem ao modelo relacional. Não vou entrar nos casos que este modelo não se aplica bem, afinal não seria bem o caso de desnormalizar.

Curso de PHP ERP com NFe.

Eu só vejo um grande motivo interessante para desnormalizar um banco de dados.

Performance

Após ser medido que o projeto físico está atrapalhando a performance e consequentemente a escalabilidade do banco de dados, pode ser interessante desnormalizá-lo com critério. Não significa que o projeto lógico deva ser desnormalizado.

OLAP X OLTP

O mais comum é fazer em dados ou partes do banco de dados ou mesmo em bancos específicos para OLAP. Para operações essencialmente de consulta, análise, simulação e projeção. Para aplicações de BI, Data Warehousing, etc.

Em bancos de dados simplificados, locais, rodando em equipamentos de baixa performance e capacidade que executam tarefas satélites específicas (terminal PDV, por exemplo) também podem se beneficiar do ganho de performance.

Note que em ambos a desnormalização acaba se dando mais em um banco de dados auxiliar. E quando ocorre no mesmo banco de dados, é feito em partes que são inerentemente usadas para consultas. Em atividades típicas OLTP a desnormalização não costuma ser uma opção tão interessante.

Mas copiar dados para análise realmente é desnormalização? Afeta a integridade dos dados?

Não pode.

Cria dados redundantes?

Tenho dúvidas.

Não achei referências canônicas confiáveis que determinam isto. Mas alguma coisa me diz que nunca foi intenção da normalização trabalhar em cima de atividades OLAP. Quando ela foi criada só se pensava em OLTP. A minha experiência (a sua pode variar) é que desnormalização em OLTP costuma mais atrapalhar a performance do que ajudar.

Técnicas de melhoria de performance

Na verdade não são tantos casos que realmente se beneficiam da desnormalização. É aquela coisa da moda ou entendimento pela metade, ou ainda aplicação de algo no contexto errado. Na maioria das vezes existem outras técnicas para diminuir o impacto no banco de dados antes de ter que recorrer à desnormalização. Há casos que desnormalizar resolve um problema e causa outro.

Algumas técnicas de desnormalização formais:

 

Simplificação

Outro motivo que não é muito bom mas pode ser válido e aceitável é a simplificação do banco de dados.

Existe uma diferença entre fazer o sistema da padaria do seu Manuel e um grande sistema para uma grande empresa. Permitir uma lista de telefones no cadastro de um sisteminha pode não ser problema. Mas controlar todos os contatos de uma empresa complexa não dá muita margem para cadastrar os dados de qualquer jeito. Imagine um parceiro com vários contatos que muda de número de telefone. Você quer mudar este número de telefone, provavelmente preservando os ramais internos de todos os contatos. Vai sair mudando um a um? E se precisar pesquisar os números de telefone dos contatos? É melhor ter estes dados em uma tabela separada.

Algumas simplificações podem trazer mais problemas que soluções. Garantir a integridade de dados desnormalizados pode ser complicado e arriscado. Não é simplificação real.

Conveniência

Há quem diga que desnormalizar facilita a geração de relatórios. Mas acho que isto cai na questão do OLAP. Quer ter os dados mais fáceis para o gerador de relatório? Ok, gere um conjunto de tabelas apropriadas com os dados necessários, possivelmente de forma temporária, e disponibilize para o relatório. Se você quer apenas conveniência para acesso aos dados crie views ou use outra técnica que te facilite. Desnormalização não pode ser usada para conveniência.

Pegando seu exemplo

Imagine se New York resolva se chamar Old York. Dá para consertar? Não sei. Quantas cidades New York diferentes existem no cadastro? New York não é a identidade da informação, é um estado dela. Digamos que tem como consertar. Não era para simplificar? Ou será que foi apenas XGH?

Se realmente precisa simplificar, violar a primeira forma normal é o que causará menos dificuldades. Você pode usar o tipo array do PostgreSQL ou uma técnica qualquer que simule este recurso em outros sistemas de bancos de dados. Só é complicado se o banco de dados usar tamanho fixo da linha. Pode haver muito desperdício. Mas questiono se é simplificação de verdade. Dá trabalho lidar com exceções.

Mas vale a máxima que se você realmente souber o que está fazendo, tudo é válido. O problema é que quem não sabe, também não consegue avaliar se sabe.

O que parece desnormalização mas não é.

Existem casos em que você pode pensar que está desnormalizando mas está apenas adequando o projeto ao domínio.

Um exemplo típico.

Uma nota fiscal costuma ter uma referência ao parceiro de negócios e os itens da nota costumam ter referências aos produtos vinculados. Está normalizado e duvido que alguém ache bom desnormalizar a separação dos itens do cabeçalho da nota.

Se um endereço do parceiro, um cliente por exemplo, muda após a emissão desta nota, o que acontece com o endereço constante na nota? E se o preço de um produto vendido nesta nota muda?

Você tem uma bela de uma inconsistência e está fazendo algo ilegal (pelo menos no Brasil). Trazer os dados do cliente ou do produto para a nota não é desnormalização. É garantir o arquivamento correto da informação. Os dados do cadastro geral do parceiro tem um objetivo. Os dados do cadastro do parceiro no momento da emissão da nota fiscal tem outro objetivo. São coisas diferentes. Eles podem ser coincidentes mas sincronizá-los, tentando obter consistência, causa o oposto, torna-os inconsistentes.

A semântica dos dados do parceiro constantes na nota determina que eles são imutáveis após a emissão, então você tem que garantir isto. Copiar os dados do cliente para a nota fiscal soluciona isto (é incrível como alguns sistemas, até conhecidos, descuidam disto). Copiar os dados do produto não só é necessário pela imutabilidade. Na verdade os dados podem tomar outra forma. O preço pode ser especial para esta operação, o imposto pode ser diferenciado por alguma razão específica. E a descrição também pode ser personalizada (em uma licitação a nota deve sair com a descrição do edital e não o que o vencedor da licitação tem no seu cadastro de produtos) se tornando outra informação que usou como base o cadastro de produtos. No momento que copia o dado ele é desacoplado da sua origem. Se a informação é outra, copiar não é desnormalizar. Só porque você tem o número “1” em dois lugares diferentes não significa que eles representam a mesma coisa.

Mesmo assim eu sugeriria ter uma normalização destas informações. Para garantir a imutabilidade dos dados do parceiro talvez as alterações do cadastro do parceiro deveriam ser feitas em multi-versão. Aí é possível se referenciar direto para a versão ativa no momento da emissão da nota. Criar múltiplas versões do cadastro pode parecer desnormalização. Mas se você precisa da informação repetida, se está na semântica do mecanismo, normalizar é impossível, qualquer tentativa neste sentido é destruir o mecanismo.

Este mecanismo tem vantagens até mesmo para resolver outros problemas e é útil em vários casos. Mas também tem desvantagens. Por isso outra solução de normalização mais pura para o intuito pode ser mais viável em outros casos.

Tenha uma tabela só com os dados necessários dos parceiros quando eles são usados em uma nota fiscal. Uma nova versão destes dados só será cadastrada se houver alterações no cadastro quando emitir uma nova nota para o parceiro. Desta forma evita-se ter cópias de dados que não são usados em nenhuma nota fiscal e ter cópias de dados que não mudam por anos. Este modelo me parece tão óbvio que me parece constrangedor que os sistemas não utilizem alguma variação dele.

Já entrei em detalhes demais sobre isto. O que importa é que o ideal é mudar a normalização e não desnormalizar, até porque o requisito do sistema usa outra informação.

Campos calculados

Se você está usando campos acumuladores ou outros calculados pode estar criando uma nova informação ou não. Há casos que ele é realmente redundante e cabe uma normalização e consequentemente uma desnormalização pode ser útil para melhorar a performance (ver primeira seção). Em casos extremos há cálculos que podem levar horas.

Mas muitos casos o campo simplesmente tem uma necessidade própria. Exemplo: deixar para um valor monetário ser convertido para outra moeda só quando você precisa é uma normalização que pode lhe trazer problema na contabilização. Este é um campo calculado que gera nova informação, ele não pode ser normalizado, portanto não pode ser desnormalizado.

Muitas vezes pensamos em desnormalizar o que não estava normalizado. Isto não faz sentido.

Gambiarra

É, vamos ser francos, às vezes precisamos fazer gambiarras 🙂 Não é interessante, mas necessário. Este é um motivo para desnormalizar.

Conclusão

Não coloquei mais exemplos específicos porque acho que viraria lista, se tornaria muito amplo.

Quer um bom motivo para não desnormalizar? É difícil definir bem como fazer isto ao contrário da normalização que é um conceito relativamente simples e bem conhecido. Sem um bom domínio do SQL ou do modelo relacional e ferramentas de medição e capacidade de interpretação dos resultados, é altamente provável que a desnormalização piorará a situação.

Por outro lado prender-se demais à teoria para um lado ou para o outro vai trazer mais problemas que soluções. Eu poderia dizer que fazer X viola a forma normal Y e isto não pode. Mas pode trazer vantagens sem causar nenhum problema no caso específico.

Eu conheço programadores e DBAs que vão dizer o contrário de tudo isto. Eu mesmo não sigo sempre o que eu disse aqui.

Foi bom revisitar o assunto porque descobri coisas que eu não sabia. Só não postei por estar fora do escopo.

Top
%d blogueiros gostam disto: