As cinco formas normais e porque você deve utilizá-las

Luiz Rosa
8 min readSep 22, 2017

--

Este artigo baseia-se no trabalho de William Kent, “A Simple Guide to Five Normal Forms In Relational Database Theory”, de 1982. Trata-se de um trabalho clássico, essencial para qualquer desenvolvedor ou administrador de banco de dados. O objetivo é trazer de forma objetiva a essência deste texto, adaptando ao contexto de um iniciante em bancos de dados relacionais.

O que é uma forma normal

Antes de começar a falar sobre as cinco formas normais, é fundamental que o leitor situe-se sobre o que é uma forma normal e para que ela serve.

Uma forma normal, no contexto de bancos de dados, refere-se à uma diretriz, uma convenção com o objetivo de prevenir anomalias e inconsistências em meio às atualizações frequentes que uma base irá sofrer, minimizando a redundância ao preço de uma menor eficiência entre consultas.

Uma vez em um banco de dados não normalizado, uma consulta pode depender de uma única tabela, com a normalização, o que era antes um select simples pode passar a demandar a combinação de diversas tabelas. Por isso, não há a obrigação de se normalizar o banco de dados por completo quando a performance, a eficiência entre consultas está em jogo.

A normalização é um fator que toma como pressuposto que a base sofrerá constantes atualizações. Se trata-se de uma base estática e muito consultada, não há fortes motivos para se normalizar.

Primeira Forma Normal

A Primeira Forma Normal (ou 1FN) refere-se ao formato de um registro. Esta diretriz exclui a possibilidade de haverem campos que possuem mais de um atributo, ou seja, um vetor ou grupo de atributos

Por exemplo, suponha que um usuário possua vários telefones, um design que violaria a Primeira Forma Normal seria:

Tabela para Usuários

Note que um usuário pode ter vários telefones, mas estes estão dispostos em um único atributo, telephone. Para encontrar um usuário com determinado telefone, teríamos de aplicar um select por padrão de texto (LIKE %..%), o que seria extremamente custoso, além de poder trazer resultados indesejados.

Outro problema também é a possibilidade de que um usuário possua dois telefones iguais e a falta de controle na garantia de determinadas regras de integridade: e se quiséssemos restringir que um telefone é único, apenas de um usuário?

Um esquema está na Primeira Forma Normal se e somente se o domínio de todos os seus atributos são atômicos.

Para resolver o problema dos atributos compostos, uma boa abordagem seria uma tabela separada, como users_telephones, que armazenasse um único telefone para o id de um único usuário. Este esquema estaria na Primeira Forma Normal.

Usuários agora em duas tabelas, seguindo a 1FN

Note que agora um usuário pode ter zero, um ou mais telefones, porém de uma forma muito mais elegante e organizada.

Segunda Forma Normal

Esta forma normal refere-se ao relacionamento entre atributos dentro de uma determinada tabela, mais especificamente entre atributos chave e não-chave, tomaremos daqui em diante “chave” como chave primária, não considerando chaves estrangeiras.

Um esquema está na Segunda Forma Normal (2FN) se está na 1FN e se cada atributo não chave de uma tabela refere-se à chave da mesma como um todo. Isso parece um pouco confuso, porém fica muito mais evidente quando explicitamos os problemas que podem decorrer de um atributo que refere-se apenas à parte de uma chave. Note que este é um caso aplicável à chaves primárias compostas, ou seja, aquelas que são formadas por mais de um campo.

Tabela para produtos em lojas

No exemplo acima, a chave primária seria a composição entre product_id e store_id, de modo que os preços de cada produto em cada loja sejam armazenados. Contudo, note que store_street refere-se somente a store_id e não a product_id, logo, refere-se à parte, subconjunto da chave primária.

Os problemas que disso poderiam decorrer são:

  • Duplicação de dados: teremos a rua da loja a cada registro, de forma repetida.
  • Atualização múltipla: para manter o banco em um estado consistente, sempre que o endereço da loja mudar, temos de mudar todos os registros repetidos.
  • Dependência de registros: se não houver nenhum produto em determinada loja, como saberemos o endereço daquela loja?

Para que o esquema enquadre-se na Segunda Forma Normal, teremos de novamente dividir as coisas. Podemos separar o endereço do registro de preços, de modo que seja escrito uma única vez.

Produtos em loja passou a ser mais específica, removendo um fato que era sobre parte da chave

Eliminamos a repetição de atributos, organizamos melhor nossa base de dados e economizamos espaço.

Terceira Forma Normal

A Terceira Forma Normal (3FN) é bastante semelhante a segunda e também refere-se a chaves. Além disso, ela também requer que antes a Primeira Forma Normal seja satisfeita. Esta diretriz é violada quando um atributo não chave refere-se a outro atributo que também não é chave dentro de uma tabela.

Tomemos como exemplo uma tabela de projetos universitários:

Tabela para projetos em universidades

O telefone da universidade não refere-se ao projeto, que é a chave, mas sim à universidade, um atributo não chave. Os problemas daí decorrentes são os mesmos que pontuamos na Segunda Forma Normal:

  • Repetição de dados: note que o telefone deve se repetir entre os registros.
  • Atualização múltipla: sempre que alterar-se o telefone de uma universidade, este telefone terá de ser atualizado em todos os registros que a mesma fizer parte, ou cairemos no próximo problema.
  • Inconsistência: diferentes registros podem mostrar diferentes valores (qual deles é o correto?).
  • Dependência de registros: se não houver nenhum projeto em uma universidade, onde estará o seu telefone?

Por fim, para que a tabela enquadre-se na Terceira Forma Normal, teremos de remover o telefone e delegar à uma tabela específica da universidade.

Tabela para projetos em universidades também ficou mais específica, removendo atributos que não diziam repeito a sua chave

Novamente, eliminamos repetições e economizamos espaço. Em resumo:

Um esquema está na Segunda e Terceira Forma Normal se todo campo é parte da chave ou provê um fato sobre toda a chave, nunca uma parte dela.

Quarta Forma Normal

Até este ponto nosso banco de dados já está bastante organizado e eliminamos diversos débitos técnicos que poderiam nos gerar dores de cabeça. Porém ainda podemos ir mais longe.

A Quarta Forma Normal (4FN) fala sobre fatos multivalorados, ou seja, sobre relacionamentos muitos-para-muitos e muitos-para-um. De uma forma mais específica, para que um esquema enquadre-se nesta diretriz, este deve estar na 3FN e não pode conter dois ou mais fatos multivalorados independentes. O objetivo desta restrição é tentar minimizar o número de campos da chave composta de uma entidade. Esta definição é bastante confusa, porém vamos tentar entendê-la:

Considere um cenário onde um empregador gostaria de armazenar dados a respeito das muitas habilidades e línguas que cada funcionário seu pode possuir, no seguinte esquema:

Esquema para um relacionamento entre empregados, habilidades e idiomas

Temos aqui duas relações muitos-para-muitos: empregados versus habilidades e empregados versus idiomas. Pela Quarta Forma Normal estes relacionamentos não devem ser armazenados em uma única tabela. Este tipo de esquema leva a incertezas no ciclo de manutenção de uma base, já que podemos ter diversas formas de enxergar como armazenar os dados.

  • Podemos armazenar um formato disjunto, onde cada registro contém ou uma habilidade ou um idioma, e nunca ambos, o que seria a mesma coisa do que armazenar em duas tabelas diferentes.
Tabela armazenando valores disjuntos
  • Podemos armazenar o mínimo possível, com valores nulos nas lacunas.
Tabela armazenando o mínimo possível, com lacunas nulas
  • Podemos armazenar o mínimo possível, com repetições nas lacunas.
Tabela armazenando o mínimo possível, com repetição em lacunas
  • Podemos abrir mão de qualquer restrição.
Tabela armazenando valores sem qualquer restrição
  • Podemos fazer um produto cartesiano de habilidades e idiomas, onde todas as possibilidades possíveis são armazenadas.
Produto cartesiano habilidades x idiomas

Note a ambiguidade que tal esquema pode gerar: o que significam, afinal, os valores nulos? Que a pessoa não possui a habilidade? Que não se aplica a seu perfil como empregado? Que é um valor desconhecido? Ou que isso está armazenado em outro registro?

Manter uma base de dados desta forma geraria um verdadeiro pesadelo. Para cada uma das abordagens acima existem os seus próprios problemas, que também decorrem daqueles que citamos para a 2FN e 3FN.

  • Se houverem repetições, eventuais atualizações terão de ser feitas em vários registros sempre.
  • A inserção de uma nova habilidade deve envolver buscar um registro com este campo nulo ou inserir um novo registro com o campo de idioma nulo, ou ainda inserir um registro para cada cruzamento com idioma possível.
  • Excluir uma habilidade envolve tornar nulo este campo em um ou mais registros, garantindo que não hajam dois idiomas repetidos com a habilidade nula, ou ainda excluindo um ou mais registros, garantindo que nenhum idioma foi excluído neste montante.

Por fim, como resolvemos este problema? Mais uma vez, separando as coisas. Para o caso acima, bastaria que para cada relacionamento entre empregado e alguma coisa, houvesse uma tabela específica para este relacionamento e não uma tabela que misture mais de um relacionamento.

Esquema normalizado, relacionamento feito em duas tabelas distintas

Quinta Forma Normal

Por fim, a Quinta Forma Normal. Direto ao ponto, para que um esquema enquadre-se nesta diretriz, primeiramente ele deve estar em todas as formas normais vistas anteriormente e, se estiver na 4FN, muito provavelmente estará também na quinta.

A Quinta Forma Normal (5FN) trata os casos onde uma determinada informação pode ser reconstruída de informações menores combinadas. Ela em nada difere da 4FN se não houver uma constante simétrica que atue como uma regra de mundo entre as tabelas em questão. Na ausência desta contante, se o esquema estiver na 4FN, automaticamente estará, também, na 5FN.

Em exemplos, suponha que armazenemos, tuplas do tipo “um vendedor vende produto x para a empresa y”, da seguinte forma:

Tabela para vendedores que vendem para empresas determinados produtos

Até este ponto, o esquema está na Quarta Forma Normal pois os fatos multivalorados empresa e produto são dependentes. E se pensarmos que o vendedor só vende produtos específicos para cada empresa, também estará na Quinta Forma Normal.

Porém, supomos que uma nova regra de mundo é aplicada: Se um vendedor vende um tipo de produto e também vende para determinada empresa, então este vendedor vende aquele produto para aquela empresa. Ou seja, se ele vende discos rígidos e vende para a Apple, automaticamente vende discos rígidos da Apple. Se esta regra de mundo for verdadeira, então o esquema não estará mais na Quinta Forma Normal, pois uma constante simétrica foi aplicada. Neste caso, para que o esquema enquadre-se na 5FN seria necessário separar o que ele vende de para quem ele vende.

Se o vendedor vendia para a Apple e vendia discos rígidos, agora ele vende discos rígidos para a Apple

Este esquema gera repetição de dados. Sabe-se que ele vende discos rígidos e celulares e, vende para a Samsung e a Apple. Por que então cruzar essas informações em uma espécie de produto cartesiano?

Separamos as informações em três partes menores e eliminamos a repetição

Desta forma, eliminou-se a repetição de dados, dividindo a informação em três partes: As empresas para qual o vendedor vende, os produtos que ele vende e os produtos que a companhia vende.

Conclusão

A normalização, embora pareça, não elimina todas as redundâncias possíveis. As redundâncias exibidas neste artigo são muito simples se comparadas ao mundo real e tratam de tabelas sozinhas (embora tratem de relacionamentos, as redundâncias abordadas encontravam-se em uma única entidade cada). Existe ainda a redundância entre múltiplas tabelas, que não é o foco deste texto.

Contudo, o maior ganho em se tratando de normalização é pagar o preço em um design mais elaborado em troca de manutenibilidade e consistência dos dados, além é claro do preço em performance quando consultas complexas passam a demandar a combinação de várias tabelas para retornar o resultado final.

--

--

Luiz Rosa
Luiz Rosa

Written by Luiz Rosa

Computer Science BSc, fullstack developer.

Responses (5)