A normalização do banco de dados é o processo de transformações na estrutura de um banco de dados que visa a eliminar redundâncias e a eliminar anomalias de inserção, atualização e exclusão.
Atualizado em 28/11/2024.
A normalização de banco de dados é o processo de organizar as tabelas de um banco de dados de forma a minimizar redundâncias e a preservar a integridade dos dados. A normalização é feita através da divisão de tabelas grandes em tabelas menores e mais específicas, o que ajuda a evitar problemas como dados inconsistentes ou repetidos.
Existem vários níveis de normalização, conhecidos como Formas Normais (1FN, 2FN, 3FN, etc.), que definem regras rigorosas para a estruturação de tabelas. Alguns exemplos práticos incluem:
- 1FN (Primeira Forma Normal): Em 1FN, cada coluna em uma tabela deve conter apenas valores atômicos, ou seja, valores indivisíveis que não possam ser divididos em outros valores. Por exemplo, uma tabela de clientes pode ter colunas para nome, endereço e número de telefone, mas não pode ter uma coluna para “nome e endereço”.
- 2FN (Segunda Forma Normal): Em 2FN, cada coluna não-chave em uma tabela deve estar dependente funcionalmente da chave primária da tabela. Por exemplo, em uma tabela de clientes, o endereço pode estar dependente do número de identificação do cliente, mas não pode estar dependente apenas do nome do cliente.
- 3FN (Terceira Forma Normal): Em 3FN, todas as informações que não sejam dependentes da chave primária da tabela devem ser removidas para outra tabela. Por exemplo, em uma tabela de clientes, informações sobre pedidos podem ser removidas para uma tabela de pedidos separada, ligada à tabela de clientes por meio de uma chave estrangeira.
Estes são apenas alguns exemplos simples, mas a normalização pode ser bastante complexa em situações reais, envolvendo várias tabelas e relações. A normalização é uma parte importante do projeto de banco de dados, e é importante que seja feita corretamente para garantir a integridade e a performance dos dados ao longo do tempo.
Conta Exclusiva ChatGPT: Acesso Ilimitado
Desbloqueie o poder do ChatGPT com recursos premium. Aproveite 80,5% de desconto e garantia de 100% de satisfação. Junte-se hoje e viva a melhor experiência de chat com IA!
Cypress, do Zero à Nuvem: domine a automação de testes com confiabilidade e eficiência
Aprimore suas habilidades de automação de testes com Cypress, desde o início até a integração contínua.
Saiba Mais💻 Torne-se um Desenvolvedor Fullstack!
Domine as tecnologias mais requisitadas do mercado e conquiste sua carreira dos sonhos como Desenvolvedor Fullstack. Inscreva-se hoje!
Inscreva-seAo efetuar o processo de normalização, os dados cadastrados no banco de dados ficarão organizados de uma forma melhor e na maioria das vezes também ocuparão menos espaço físico. Entretanto, o processo de normalização também sempre faz aumentar o número de tabelas e em muitos casos pode ser uma tarefa difícil de ser realizada. Além disso, bancos de dados normalizados além do necessário podem ter desempenho ruim e/ou complexidade excessiva.
Anomalias
A principal finalidade do processo de normalização é eliminar as anomalias de inserção, atualização e exclusão. A anomalia ocorre quando não há forma de se cadastrar alguma determinada informação sem que alguma outra informação também seja diretamente cadastrada. Por exemplo, imagine que você tenha uma tabela funcionário
com os seguintes dados: codigo
, nome
, projeto
, onde a coluna projeto
corresponde ao nome do projeto no qual um funcionário foi alocado. E então você tem os seguintes dados:
codigo | nome | projeto |
---|---|---|
1 | Pedro | Vendas |
2 | Maria | Vendas |
3 | Carlos | Cadastro de clientes |
E então surgiu um projeto novo: O de emissão de notas fiscais. Como você cadastra esse novo projeto? A resposta é que não dá para cadastrar, pois para fazer isso você teria que ter algum funcionário nesse projeto – ou seja, temos uma anomalia de inserção.
Se no exemplo anterior, o funcionário Carlos fosse desligado da empresa e o removermos da tabela, a informação sobre o projeto de cadastro de clientes é perdida. Isso é um efeito colateral indesejado – é a anomalia de exclusão. Se no entanto ele apenas fosse remanejado para o novo projeto de notas fiscais, nós também perderíamos a informação acerca da existência do projeto de cadastro de clientes – essa é a anomalia de alteração.
LEIA TAMBÉM:
O problema que origina essas anomalias é o fato de a informação do projeto estar toda dentro da tabela de funcionários, que não é o lugar dela. Se tivermos duas tabelas relacionadas (1-para-N) – funcionários e projetos – as anomalias desaparecem.
Anomalias também têm relação com o conceito de integridade referencial.
O que é integridade referencial?
Integridade referencial é um conceito relacionado à chaves estrangeiras. Este conceito diz que o valor que é chave estrangeira em uma tabela destino, deve ser chave primária de algum registro na tabela origem. Quando essa regra é desrespeitada, então temos o caso em que a integridade referencial é violada.
Vejamos a terminologia: Integridade vem de íntegro, inteiro, completo, correto. Referencial vem de referência, indicar algo ou alguém. Portanto, integridade referencial é indicar algo ou alguém de forma íntegra, completa, correta.
Por exemplo, veja essas duas tabelas:
Carros
Placa (PK) | Modelo | Proprietário (FK)
-----------+--------+------------------
ABC-1233 | Passat | 1
DEF-4566 | Fiesta | 2
UUV-7890 | Palio | 1
Proprietários
ID (PK) | Nome
--------+------
1 | Pedro
2 | Maria
Estas tabelas têm integridade referencial, pois os carros que têm proprietário com ID 1, podem ser encontrados na tabela de proprietários como sendo do Pedro. O carro de proprietário com ID 2 pode ser encontrado como sendo da Maria.
Agora, imagine que nós venhamos inserir um carro de placa EJB-6520, do modelo Celta e do proprietário com o ID 3. Ocorre que não há nenhum proprietário de ID 3. Se o banco de dados permitir essa inclusão, ocorrerá uma violação da integridade referencial, pois estará sendo feita uma referência a uma entidade inexistente. O mesmo ocorreria se quisermos alterar o proprietário de um dos carros colocando o ID do proprietário como 3.
Por outro lado, se nós quisermos deletar a Maria do banco de dados sem deletar o carro de placa DEF-4566 e nem alterá-lo, novamente teremos uma violação da integridade referencial, pois se o banco de dados permitir que essa exclusão seja feita, a integridade referencial será violada ao termos um carro que tem como dono, uma entidade agora inexistente.
A maioria dos bancos de dados relacionais modernos existentes impõem integridade referencial quando você tenta inserir, alterar ou excluir entidades no qual há chaves estrangeiras envolvidas. Entretanto, o MySQL quando utilizado com engine MyISAM é uma notável exceção (o recomendável é utilizar InnoDB nesses casos). Também é possível que as tabelas tenham sido modeladas sem que a chave estrangeira tenha sido explicitamente modelada no banco de dados e fique apenas implícita no nível da aplicação, e portanto o banco de dados não terá como verificar a integridade nesse caso.
Se uma violação de integridade ocorrer, o seu banco de dados apresentará registros inconsistentes que apontam para entidades que não existem, o que tende a se manifestar nas aplicações sob a forma de vários tipos de problemas.
Primeira forma normal (1NF)
A primeira regra para eliminar as anomalias é:
Não devem existir colunas multivaloradas.
O que é uma coluna multivalorada? É uma coluna na qual é possível armazenar-se mais de um valor por registro. Por exemplo, imagine que você tenha na sua tabela de clientes as colunas codigo
, nome
e telefones
, preenchidos assim:
codigo | nome | telefones |
---|---|---|
1 | Paulo | 99567-4289, 3605-4900 |
2 | Maria | 97223-0444 |
3 | Alan | – |
4 | Juliana | 2853-0266, 96610-5480, 2410-9941 |
Observe que a coluna de telefones é multivalorada. Inserir, atualizar e excluir telefones nesse esquema é algo complicado de se fazer. Pesquisar por algum número de telefone específico também é algo complicado. A solução para isso é dividir em duas tabelas:
Cliente:
codigo | nome |
---|---|
1 | Paulo |
2 | Maria |
3 | Alan |
4 | Juliana |
Telefone:
codigo | codigo_cliente | numero |
---|---|---|
1 | 1 | 99567-4289 |
2 | 1 | 3605-4900 |
3 | 2 | 97223-0444 |
4 | 4 | 2853-0266 |
5 | 4 | 96610-5480 |
6 | 4 | 2410-9941 |
Ao eliminar-se todas as colunas multivaloradas, o banco de dados atinge uma forma estrutural denominada de primeira forma normal, ou simplesmente 1FN.
Chaves candidatas e superchaves
Antes de prosseguir com as demais formas normais, faz-se necessário introduzir-se os conceitos de chaves candidatas e superchaves.
A chave primária (primary key, ou apenas PK) é aquele conjunto de colunas que serve para identificar a tupla de uma forma única (pode ser só uma coluna, ou podem ser duas ou mais). É importante que o projetista do banco de dados saiba identificar quais são as colunas mais apropriadas para serem eleitas como parte da chave primária. Muitas vezes, uma coluna com um código numérico sequencial pode servir para ser a chave primária, mas há várias situações onde esse não é o caso.
Às vezes, há mais do que um conjunto de colunas que poderia ser chave primária. Cada um desses conjuntos é chamado de chave candidata. Por exemplo, em uma tabela Pessoa
que tenha os campos CPF
, RG
, Estado
e Nome
, tanto o CPF
quanto o RG
junto com o Estado
são chaves candidatas. Assim, é possível chegar-se ao Nome
a partir do CPF
, mas também é possível chegar-se ao Nome
a partir do RG
e do Estado
.
Qualquer conjunto de colunas que tenha como subconjunto, uma chave candidata é denominado de superchave.
Segunda forma normal (2FN)
A segunda forma normal é aquela que diz que:
Todas as colunas devem ter dependência funcional com a totalidade de cada chave candidata.
Na maioria dos casos por “cada chave candidata“, entenda-se por “com a chave primária“, exceto se houver mais do que uma chave candidata.
Além disso, para que uma tabela esteja na segunda forma normal, ela deve estar antes de tudo, na primeira forma normal.
Uma coluna está em dependência funcional com a chave primária quando ela é determinada no domínio da aplicação por meio da chave primária. Uma coluna não tem dependência funcional com a chave primária quando ela é definida de forma independente da chave primária ou quando ela é definida a partir de alguma outra coluna que não seja a chave primária.
Uma dependência funcional pode ser dita estar na totalidade da chave primária quando todos os campos da chave primária são necessários para estabelecer-se a relação de dependência. No caso de a chave primária ser composta, é possível se ter uma dependência parcial.
Para dar um exemplo da 2FN, imagine que sua empresa tenha representantes comerciais atuando em clientes e queira representar a relação de quais representantes comerciais atuam em quais clientes. Nessa tabela (vamos chamar de representação
), temos as colunas nome_cli
para o nome do cliente e nome_repr
para o nome do representante como chaves primárias e temos também as colunas end_repr
para o endereço do representante, end_cli
para o endereço do cliente e valor_contrato
. Ou seja:
Representação:
nome_cli (PK) | nome_repr (PK) | end_repr | end_cli | valor_contrato |
---|---|---|---|---|
Luís | Cleyton | Rua A 888 | Rua X 123 | R$ 500,00 |
Paula | Lara | Rua B 999 | Rua Y 345 | R$ 900,00 |
Paula | Cleyton | Rua A 888 | Rua Y 345 | R$ 650,00 |
Observe que as colunas end_repr
e end_cli
dependem da chave primária. Mas eles não dependem de toda a chave primária, cada um depende apenas de parte dela. A solução neste caso é ter uma tabela de clientes (com o endereço do cliente), uma tabela de representantes comerciais (com o endereço dele também) e deixar na tabela de atuação as respectivas chaves estrangeiras com o valor do contrato. Ou seja:
Clientes:
nome_cli (PK) | end_cli |
---|---|
Luís | Rua X 123 |
Paula | Rua Y 345 |
Representantes:
nome_repr (PK) | end_repr |
---|---|
Cleyton | Rua A 888 |
Lara | Rua B 999 |
Representação:
nome_cli (PK) | nome_repr (PK) | valor_contrato |
---|---|---|
Luís | Cleyton | R$ 500,00 |
Paula | Lara | R$ 900,00 |
Paula | Cleyton | R$ 650,00 |
Terceira forma normal (3FN)
A terceira forma normal é aquela que diz que:
Todas as colunas devem ter dependência funcional com a totalidade de cada chave candidata e nada mais além do que essas chaves candidatas.
Novamente, na maioria dos casos por “cada chave candidata“, entenda-se por “com a chave primária“, exceto se houver mais do que uma chave candidata. Se a única chave candidata existente for a chave primária, isso ficaria assim:
Todas as colunas devem ter dependência funcional com a totalidade da chave primária e nada mais além da chave primária.
Além disso, para uma tabela estar na terceira forma normal, ela deve estar primeiramente na segunda forma normal (e também na primeira). A parte de depender da totalidade de cada chave candidata é abordada na segunda forma normal, então o foco aqui é depender de nada mais que essas chaves.
Por exemplo. Imagine a tabela de carros com as colunas placa
(chave primária), cor
, nome_proprietário
, endereço_proprietário
:
placa (PK) | cor | nome_proprietário | endereço_proprietário |
---|---|---|---|
ABX-1234 | azul | José | Rua X, 123 |
NNU-5566 | verde | Marcos | Rua exemplo, 5678 |
SGH-7210 | preto | Maria | Avenida teste, 7743 |
ERT-6902 | vermelho | José | Rua X, 123 |
BGH-5431 | preto | José | Rua X, 123 |
Observe o endereço do proprietário – ele é uma violação da terceira forma normal. Observe que o endereço do proprietário é definido como resultado de quem é o proprietário, e não como consequência da placa do carro. Se o José mudar de endereço e atualizarmos o endereço de apenas um dos carros dele, o banco de dados ficará inconsistente (há anomalia de alteração). Se a Maria comprar mais um novo carro e adicionarmos com um outro endereço, também ficará inconsistente (anomalia de inserção). Se o Marcos vender o carro dele, o seu endereço será esquecido (anomalia de exclusão). A solução novamente, é separar em duas tabelas:
Carro:
placa (PK) | cor | proprietário |
---|---|---|
ABX-1234 | azul | 1 |
NNU-5566 | verde | 2 |
SGH-7210 | preto | 3 |
ERT-6902 | vermelho | 1 |
BGH-5431 | preto | 1 |
Proprietário:
codigo (PK) | nome | endereço |
---|---|---|
1 | José | Rua X, 123 |
2 | Marcos | Rua exemplo, 5678 |
3 | Maria | Avenida teste, 7743 |
Forma normal de Boyce-Codd (BCNF)
Existe uma forma normal que é um pouco mais forte que a terceira forma normal, mas que não é requisito necessário para atingir-se a quarta (ou mesmo a sexta). Essa é a forma normal de Boyce-Codd (BCNF), também chamada por vezes de 3.5NF ou de forma normal de Boyce-Codd-Heath.
É bem raro encontrar-se casos de tabelas que estejam na terceira forma normal, mas não na forma normal de Boyce-Codd. Além disso, existem casos (incomuns) onde essa forma normal é impossível de ser atingida (diferentemente das formas entre a primeira e a sexta, que sempre podem ser atingidas).
A diferença aparece quando há mais do que uma chave candidata e elas têm alguma intersecção. A ideia é que os campos que são chaves candidatas sempre determinem os demais campos, e nunca sejam determinados por esses. Assim sendo, na forma normal de Boyce-Codd não é permitido chegar-se a uma chave candidata com base em alguma outra chave candidata por meio de dependências funcionais.
Vamos dizer que cada pizza pode ter várias coberturas diferentes, cada uma de um tipo diferente e que você tem dois tipos de pizzas com essas coberturas:
Pizza | Cobertura | Tipo de cobertura |
---|---|---|
1 | muçarela | queijo |
1 | pepperoni | carne |
1 | azeitonas | vegetal |
2 | muçarela | carne |
2 | linguiça | queijo |
2 | pimenta | vegetal |
Há duas chaves candidatas aí: Pizza e tipo de cobertura definem a cobertura usada. Uma outra chave candidata é que a partir da pizza e da cobertura utilizada, nós podemos definir o tipo da cobertura utilizada.
Note que para qualquer que seja a chave candidata que nós olhamos, a demais coluna depende da totalidade da chave candidata e de nada mais do que a chave candidata, então a terceira forma normal foi atingida.
Bem, tem algo errado aí, pois linguiça não é um queijo e muçarela não pode ser carne e queijo ao mesmo tempo – apesar de termos atingido a terceira forma normal, ainda temos anomalias.
A solução é novamente dividir em duas tabelas:
Pizza (PK) | Cobertura (PK) |
---|---|
1 | muçarela |
1 | pepperoni |
1 | azeitonas |
2 | muçarela |
2 | linguiça |
2 | pimenta |
Cobertura (PK) | Tipo da cobertura |
---|---|
muçarela | queijo |
pepperoni | carne |
azeitonas | vegetal |
linguiça | carne |
pimenta | vegetal |
Quarta forma normal (4FN)
É raro encontrar-se casos de tabelas que estejam na terceira forma normal, mas não na quarta. A quarta forma concerne em anomalias existentes na relação entre diferentes colunas da chave primária, e só se aplica em tabelas com chaves primárias compostas por três colunas ou mais.
Tabelas que representem relacionamentos ternários, quaternários ou n-ários de muitos-para-muitos são locais onde vale dar-se uma olhada em possíveis violações da 4FN.
Para uma tabela estar na quarta forma normal, ela tem que primeiramente estar também na terceira forma normal. A forma normal de Boyce-Codd não é necessária.
É meio difícil de se explicar, mas imagine que tenhamos o caso de representantes comerciais atuando em clientes, onde vários representantes podem atuar em vários clientes e que tenhamos contratos de prestação de serviços em que vários representantes atuam em vários contratos. E então temos a seguinte tabela, onde todas as colunas são chave primária:
representante | contrato | cliente |
---|---|---|
Geraldo | 1 | loja de roupas |
Geraldo | 1 | hospital |
Geraldo | 2 | loja de roupas |
Geraldo | 2 | hospital |
Marta | 1 | loja de brinquedos |
Marta | 1 | hospital |
Marta | 3 | loja de brinquedos |
Marta | 3 | hospital |
Luís | 2 | loja de roupas |
Luís | 2 | loja de brinquedos |
Luís | 4 | loja de roupas |
Luís | 4 | loja de brinquedos |
Observe que temos relações de muitos-para-muitos entre representantes e contratos e entre representantes e clientes. Mas não temos entre clientes e contratos! Aqui está a violação da forma normal e a possibilidade de se ter algum tipo de anomalia. O ideal é separar em duas tabelas, uma com a relação entre representantes e clientes e outra com a representação entre representantes e contratos:
representantes | contratos |
---|---|
Geraldo | 1 |
Geraldo | 2 |
Marta | 1 |
Marta | 3 |
Luís | 2 |
Luís | 4 |
representantes | clientes |
---|---|
Geraldo | loja de roupas |
Geraldo | hospital |
Marta | loja de brinquedos |
Marta | hospital |
Luís | loja de roupas |
Observe que na tabela original, nós temos informações redundantes. Por exemplo, a informação que Marta está no contrato 1 aparece duas vezes. Se deletássemos a tupla Marta-1-hospital, teríamos uma anomalia de exclusão, vez que Marta atua no hospital (contrato 3) e Marta está no contrato 1 (na loja de brinquedos). Também temos uma anomalia de inserção no caso de termos algum representante alocado para algum contrato no qual não haja ainda nenhum cliente.
Quinta forma normal (5FN)
A quinta forma normal é mais restrita que a quarta, e também se aplica à tabelas com 3 ou mais colunas na chave primária. Novamente, para que a quinta forma normal seja atingida, é necessário atingir-se a quarta forma normal primeiramente.
Vamos imaginar um caso semelhante ao que usei na quarta forma normal, mas que dessa vez além de existir a relação entre representantes e clientes e entre representantes e contratos, também temos a relação entre clientes e contratos. Dessa forma, temos essa tabela:
representante | contrato | cliente |
---|---|---|
Geraldo | 1 | loja de roupas |
Geraldo | 1 | hospital |
Geraldo | 2 | loja de roupas |
Marta | 1 | hospital |
Marta | 3 | loja de brinquedos |
Marta | 3 | hospital |
Luís | 2 | loja de roupas |
Luís | 4 | loja de brinquedos |
Observe que essa tabela é diferente daquela que usamos na quarta forma normal. Há algumas redundâncias, como por exemplo ela diz duas vezes que Geraldo está na loja de roupas e que o contrato 1 é aplicado ao hospital. A técnica usada para colocarmos na quarta forma normal não se aplica, pois para quaisquer duas colunas obtidas da chave, existe uma relação (ou seja, temos a relação contrato-cliente também). Assim, essa relação já está na quarta forma normal, mas ainda há espaço para normalização. Ao decompormos ela em três relações diferentes, chegamos a quinta forma normal:
representantes | contratos |
---|---|
Geraldo | 1 |
Geraldo | 2 |
Marta | 1 |
Marta | 3 |
Luís | 2 |
Luís | 4 |
representantes | clientes |
---|---|
Geraldo | loja de roupas |
Geraldo | hospital |
Marta | loja de brinquedos |
Marta | hospital |
Luís | loja de roupas |
Luís | loja de brinquedos |
contratos | clientes |
---|---|
1 | loja de roupas |
1 | hospital |
2 | loja de roupas |
3 | loja de brinquedos |
3 | hospital |
4 | loja de brinquedos |
Sexta forma normal (6FN)
Para uma tabela chegar a sexta forma normal, ela primeiramente deve estar na quinta forma normal. Ela dita que:
Toda tabela só pode ter uma ou nenhuma coluna que não seja parte da chave primária.
Encontrar casos onde a quinta forma normal foi atingida mas a sexta não, é fácil: Qualquer tabela com duas ou mais colunas que não sejam chave primária são uma violação da sexta forma normal.
Entretanto, encontrar-se casos onde a sexta forma normal faça sentido de ser aplicada e traga algum benefício real com isso é bem raro – na maior parte dos casos aplicá-la acaba sendo maluquice, pois a aplicação desta forma normal tende a produzir uma explosão no número de tabelas sem trazer nenhum ou quase nenhum benefício com isso. A sexta forma normal não foi definida para ser algo útil na prática, ela tem mais a finalidade de ser um limite teórico que defina qual é o ponto final a partir do qual nenhuma outra normalização seria possível.
Para ver como seria o processo aqui (e também duvidar de qualquer benefício real que isso traga), imagine a tabela pessoa
com os campos codigo
(chave primária), nome
(NOT NULL
), sexo
(NOT NULL
) e cor_favorita
(NULLABLE
), e tenhamos esses registros:
codigo (PK) | nome | sexo | cor_favorita |
---|---|---|---|
1 | Marcela | F | verde |
2 | Rodolfo | M | – |
3 | Tiago | M | amarelo |
Ela seria decomposta assim:
Pessoa-nome:
codigo (PK) | nome |
---|---|
1 | Marcela |
2 | Rodolfo |
3 | Tiago |
Pessoa-sexo:
codigo (PK) | sexo |
---|---|
1 | F |
2 | M |
3 | M |
Pessoa-cor-favorita:
codigo (PK) | cor_favorita |
---|---|
1 | verde |
3 | amarelo |
Observe que cada coluna que não fazia parte de chave primária acabou indo parar em uma tabela separada. Observe também que a tabela pessoa-cor-favorita
não tem um registro para o elemento 2 (o Rodolfo). Essa forma de normalização elimina a necessidade de se ter NULLABLE
em colunas, e todas as colunas resultantes são NOT NULL
. Os casos das colunas que eram nulos simplesmente acabaram sendo omitidos dos registros resultantes.
Forma normal de domínio-chave (DKNF)
A forma normal de domínio-chave é a que dita que:
Todas as restrições de integridade do banco de dados devem ser impostas ou por restrições de chave ou por restrições de valores de domínio.
Por restrições de chave, entende-se chaves primárias e chaves estrangeiras. Por valores de domínio entende-se o conjunto de valores válidos para cada determinada coluna.
Esta forma normal é bem forte, sendo mais forte que a quinta forma normal e que a forma normal de Boyce-Codd juntas. Porém, ela não é mais forte que a sexta, uma vez que permite a existência de várias colunas que não sejam parte da chave primária em uma mesma tabela e nem a sexta é mais forte que ela, uma vez que não há mecanismo na 6FN que garante que todas as restrições de integridade sejam modeladas tal como exige a DKNF.
Esta forma normal é o nirvana, a utopia, o estado ideal e perfeito da normalização. Entretanto, na prática, é quase impossível de se atingi-la porque qualquer banco de dados com regras de negócio com alguma complexidade provavelmente vai ter algum tipo de regra de consistência que não tem como ser modelada apenas como restrições de chave ou de valores de domínio. Entretanto, mesmo quando inatingível, um esforço para chegar próximo a ela é válido por eliminar várias possibilidades de anomalias.
Outras formas normais
Existe um algoritmo publicado (algoritmo de Barnstein) para se normalizar tabelas e levá-las até a terceira forma normal. Entretanto, pesquisas realizadas posteriormente descobriram que esse algoritmo é um pouquinho mais rígido do que a terceira forma normal exige, mas ainda sem satisfazer a forma normal de Boyce-Codd ou a quarta forma normal. Por esse motivo, a forma normal atingida por esse algoritmo foi chamada de forma normal de chave elementar (EKNF).
Uma outra forma normal existente, mais forte que a quarta forma normal e que a forma normal de Boyce-Codd juntas, porém mais fraco que a quinta forma normal e a forma normal de Boyce-Codd juntas é a forma normal de tupla essencial (ETNF). Os autores que definiram essa forma normal a colocam como uma alternativa para a quinta forma normal padrão, que embora seja mais fraca, seria tão efetiva quanto. A ETNF é atingida quando a BCNF for atingida e pelo menos uma chave candidata tiver apenas um campo. Os autores também se referem a outros trabalhos que definem a forma normal de superchaves (superkey normal form – SKNF), a forma normal livre de redundâncias (redundancy-free normal form – RFNF) e forma normal de chave completa (key-complete normal form – KCNF). A 5NF+BCNF é mais forte que a SKNF que é mais forte que a RFNF que é mais forte que a ETNF que é mais forte que a 4NF+BCNF. Também é demonstrado que a KCNF é igual a RFNF, embora tenham sido definidas por pessoas diferentes e de formas diferentes.
Ah, e é claro, temos também a forma não-normalizada (Unnormalized form), que é aquela forma que não se adéqua nem mesmo a primeira forma normal.
Até onde normalizar?
Em geral, muitos ficam satisfeitos em atingir a terceira forma normal e não se preocupam muito com as demais formas normais superiores a essa porque:
Se aplicam a casos raros, pois quando a terceira forma normal é atingida, quase sempre a Boyce-Codd, a quarta e a quinta também foram por sorte ou acidente. Isso ocorre porque é difícil se ter um caso na 3NF que não está na BCNF e também porque tabelas com três ou mais colunas na chave primária e que tenham relações de dependência entre essas colunas são algo bem raro.
Uma vez que a terceira forma normal é atingida (e provavelmente, por sorte ou acidente, a de Boyce-Codd, a quarta e a quinta também), restam bem poucas possibilidades que permitam a introdução de anomalias. Procurar atingir a sexta forma normal é em geral maluquice e não traz benefício prático algum. Procurar atingir a forma normal de domínio-chave é quase sempre impossível, embora essa busca possa revelar ainda alguma possibilidade de anomalia que possa ser eliminada.
Por vezes, para melhorar-se o desempenho do banco de dados ou simplificar-se a sua estrutura, a recomendação acaba sendo a de desnormalizar algumas coisas. Muitos sistemas com foco em dataware house ou business intelligence são normalizados só até a segunda forma normal, muitas vezes sendo concebidos a partir de estruturas que já estavam na terceira forma normal e que sofreram uma desnormalização.
Aliás, a sexta forma normal tem mais utilidade quando se pensa em desnormalização ao invés de normalização. A ideia seria procurar algumas das tabelas que tenham relacionamentos 1-para-1 e então unificá-las, efetuando assim uma desnormalização. Afinal de contas, quando os dados referentes a um registro de um determinado conceito do domínio da aplicação estão espalhados em várias tabelas com relacionamentos de 1-para-1, é um indício de que talvez eles deveriam estar numa mesma tabela.
Onde posso aplicar o conceito de normalização?
O conceito de normalização e as formas normais se aplicam somente aos bancos de dados relacionais. Outros tipos de bancos de dados que não sejam relacionais (por exemplo, uma aplicação que salve dados em arquivos organizados em pastas), também podem ter conceitos análogos a normalização para eliminar-se redundâncias, melhorar-se a estrutura e reduzir-se a possibilidade de produzirem-se anomalias. Entretanto, nesse campo, os conceitos de normalização não são tão bem definidos quanto no caso de bases de dados relacionais e cada caso terá as suas particularidades.
O caso do NoSQL em especial é bem interessante, pois a ideia dele é modelar dados que não necessitam ter uma forte consistência (o que se denomina consistência eventual), e muitas vezes os seus dados provêm de locais onde não há uma estrutura muito forte e bem definida para os dados. Por esse motivo, não faz tanto sentido falar-se em normalização em bases NoSQL quanto se faz com SQL relacional, pois a ideia do NoSQL é aceitar, tolerar e saber lidar com eventuais anomalias e ser capaz de se virar mesmo se elas surgirem. Bases de dados NoSQL sacrificam consistência em troca de escalabilidade, e por esse motivo, anomalias têm que ser toleradas. Apesar disso, ainda assim existem alguns conceitos referentes à normalização em NoSQL, mas não são tão bem definidos ou amadurecidos. Veja um pouco sobre isso aqui.
Normalização de dados e normalização de banco de dados
Para fechar a resposta a esta pergunta, normalização de banco de dados consiste na normalização da estrutura do banco de dados, enquanto que normalização de dados corresponde à normalização dos dados já existentes nas tabelas.
Entretanto, especialmente em caso de reestruturações de bancos de dados que já estão em produção, os dois conceitos andam tão juntos e misturados que nem acaba fazendo sentido falar-se em um deles sem estar falando também do outro. Daí, em muitas situações que acontecem na prática, eles acabam sendo colocados como se fossem sinônimos.
FAQ sobre Normalização de Banco de Dados
1. O que é normalização de banco de dados?
A normalização é o processo de organizar os dados em um banco de dados para minimizar redundâncias e dependências indesejadas. Ela visa dividir os dados em tabelas menores e bem definidas, estabelecendo relacionamentos claros entre elas.
2. Por que a normalização é importante?
A normalização é essencial para:
- Evitar redundâncias de dados.
- Garantir a integridade dos dados.
- Melhorar o desempenho em consultas complexas.
- Facilitar a manutenção do banco de dados, especialmente em mudanças futuras.
3. Quantas formas normais existem?
Existem seis formas normais amplamente reconhecidas:
- Primeira Forma Normal (1NF)
- Segunda Forma Normal (2NF)
- Terceira Forma Normal (3NF)
- Forma Normal de Boyce-Codd (BCNF)
- Quinta Forma Normal (5NF)
- Sexta Forma Normal (6NF)
4. O que é a Primeira Forma Normal (1NF)?
A 1NF estabelece que:
- Cada coluna de uma tabela deve conter valores atômicos (indivisíveis).
- Não deve haver grupos repetidos ou arrays em uma tabela.
Exemplo: Uma tabela com uma coluna que armazena múltiplos telefones de um cliente não está na 1NF. Para normalizá-la, criamos uma tabela separada para os telefones.
5. O que é a Segunda Forma Normal (2NF)?
A 2NF se baseia na 1NF e exige que:
- Todos os atributos não-chave sejam totalmente dependentes da chave primária.
- Deve-se eliminar dependências parciais (onde apenas parte da chave primária determina os atributos não-chave).
Exemplo: Se uma tabela possui uma chave composta (ex.: ID do Pedido e ID do Produto) e um campo como “Nome do Cliente” depende apenas do ID do Pedido, ela não está na 2NF. O campo “Nome do Cliente” deve ser movido para outra tabela.
6. Qual a diferença entre a 1NF e a 2NF?
A 1NF trata da estrutura básica, garantindo que os dados sejam armazenados em forma atômica. Já a 2NF elimina dependências parciais para garantir que cada atributo seja completamente dependente da chave primária.
7. O que é a Terceira Forma Normal (3NF)?
A 3NF se baseia na 2NF e exige que:
- Todos os atributos não-chave dependam somente da chave primária.
- Não deve haver dependências transitivas.
Exemplo: Se uma tabela contém “ID do Produto”, “Nome do Produto” e “Categoria do Produto”, onde “Categoria do Produto” depende de “Nome do Produto”, ela não está na 3NF. Deve-se criar uma tabela separada para armazenar a categoria.
8. Quando aplicar a 3NF?
A 3NF deve ser aplicada quando há dependências transitivas. Isso é comum em tabelas com muitas colunas relacionadas indiretamente.
9. O que é a Quinta Forma Normal (5NF)?
A 5NF, também chamada de Forma Normal de Projeção-Conjunção (PJNF), foca em:
- Dividir tabelas para eliminar dependências de junção multivaloradas.
Exemplo: Imagine uma tabela que armazena “Cliente”, “Produto” e “Fornecedor”. Se “Cliente” compra um “Produto”, mas o “Fornecedor” não é diretamente relacionado a “Cliente”, essa tabela não está na 5NF. Criar tabelas separadas para cada relação resolve o problema.
10. Como a 5NF melhora o banco de dados?
A 5NF:
- Elimina redundâncias mais complexas que outras formas normais não conseguem resolver.
- É especialmente útil em bancos de dados com muitos relacionamentos indiretos.
11. Qual é a diferença entre a 3NF e a 5NF?
Enquanto a 3NF elimina dependências transitivas, a 5NF aborda dependências multivaloradas, que envolvem relações mais complexas entre tabelas.
12. O que é a Segunda Forma Normal (2FN) no contexto de banco de dados?
“2FN” é frequentemente um erro tipográfico para “2NF” (Segunda Forma Normal). A 2NF é uma etapa intermediária na normalização e elimina dependências parciais.
13. Todas as tabelas devem ser normalizadas até a 5NF?
Não necessariamente. Em sistemas onde desempenho é mais crítico que integridade, como em data warehouses, pode-se optar por uma normalização parcial para evitar consultas complexas.
14. Quais são os desafios da normalização?
- Desempenho em leitura: Consultas podem ficar mais lentas devido a várias junções.
- Complexidade: Projetar tabelas normalizadas requer um entendimento profundo dos dados.
- Manutenção: Alterações no modelo de dados podem exigir a reestruturação de várias tabelas.
15. O que é desnormalização?
Desnormalização é o processo de reverter a normalização para melhorar o desempenho de leitura. Isso é útil em sistemas onde velocidade de leitura é mais importante que integridade.
Exemplo: Em um sistema de relatórios, pode-se combinar tabelas relacionadas para evitar junções.
16. Como saber se devo normalizar ou desnormalizar?
- Normalizar: Quando integridade e manutenção são prioridades.
- Desnormalizar: Quando o desempenho em leitura é crítico.
17. Quais são as ferramentas para aplicar normalização?
- Modeladores de banco de dados como MySQL Workbench, PostgreSQL pgAdmin e Microsoft SQL Server Management Studio.
- Ferramentas de diagramas ERD, como Lucidchart, dbdiagram.io e draw.io.
18. É possível automatizar a normalização?
Em partes. Ferramentas podem ajudar a identificar anomalias, mas o design lógico depende da compreensão do analista.
19. Qual é a relação entre formas normais e banco de dados NoSQL?
Embora o NoSQL, como MongoDB e Cassandra, não dependa de normalização, práticas como evitar redundâncias ainda são úteis. A normalização pode ser adaptada conforme necessário.
20. Como melhorar o desempenho de um banco de dados normalizado?
- Índices: Crie índices nas colunas mais consultadas.
- Otimização de consultas: Reduza o número de junções complexas.
- Cache: Use ferramentas como Redis para armazenar resultados de consultas.
21. Existem desvantagens em normalizar até a 5NF?
Sim, incluir muitas junções pode:
- Aumentar o tempo de execução de consultas.
- Exigir mais memória e processamento.
22. Qual a importância de conhecer a 2NF e a 5NF?
Entender a 2NF e a 5NF ajuda a criar bancos de dados eficientes, eliminando redundâncias em diferentes níveis e mantendo a consistência dos dados.
23. Como ensinar normalização de banco de dados de forma prática?
- Use exemplos reais, como uma loja virtual.
- Crie exercícios que envolvam normalizar tabelas “sujas”.
- Mostre casos onde a falta de normalização causa problemas.
24. Normalização afeta o desempenho de um sistema?
Sim, mas o impacto varia:
- Em sistemas de alta escrita, normalização é benéfica.
- Em sistemas de alta leitura, desnormalização pode ser preferível.
25. Como identificar se um banco de dados precisa de normalização?
- Dados duplicados em várias tabelas.
- Dificuldades para manter a consistência.
- Alterações frequentes que exigem múltiplas atualizações.
LEIA TAMBÉM:
Gostou deste conteúdo?
Assine o E-Zine Ramos da Informática e receba semanalmente conteúdos exclusivos focados em desenvolvimento frontend, backend e bancos de dados para turbinar sua carreira tech.
📘 Conteúdo Exclusivo
Dicas, insights e guias práticos para alavancar suas habilidades em desenvolvimento e bancos de dados.
🚀 Hacks de Carreira
Ferramentas, atalhos e estratégias para se destacar e crescer rapidamente no mercado de tecnologia.
🌟 Tendências Tech
As novidades mais relevantes sobre desenvolvimento web, mobile e bancos de dados para você se manter atualizado.
Já somos mais de 5.000 assinantes! Junte-se a uma comunidade de profissionais que compartilham conhecimento e crescem juntos no universo tech.