Ao trabalhar com bancos de dados, é comum encontrar problemas como dados redundantes e atualizações inconsistentes. A segunda forma normal é um passo de normalização de banco de dados que se baseia na primeira forma normal (1NF) para criar tabelas mais limpas e eficientes.
Compreender o 2NF é fundamental para quem trabalha com design de banco de dados ou gestão de dados, e ele estabelece a base para formas de normalização mais avançadas como a terceira forma normal (3NF). Neste artigo, vamos explorar como o 2NF funciona e como transformar tabelas para atender aos requisitos do 2NF, com exemplos práticos. Também vamos falar sobre os benefícios e desvantagens do 2NF, e os casos de uso em que ele se encaixa melhor.
Compreendendo a Segunda Forma Normal
A segunda forma normal é um passo de normalização de banco de dados focado em eliminar dependências parciais. Foi introduzida por Edgar F. Codd, o pioneiro dos bancos de dados relacionais, como parte de seu trabalho em normalização.
Antes de uma tabela poder estar no 2NF, ela deve satisfazer as regras da primeira forma normal:
- Atomicidade: Cada célula deve conter um único valor (sem grupos repetidos ou arrays).
- Linhas únicas: A tabela deve ter uma chave primária clara.
2NF vai um passo além com uma regra adicional: eliminar dependências parciais.
Uma dependência parcial ocorre quando um atributo não chave (coluna que não faz parte de nenhuma chave candidata) depende apenas de parte de uma chave composta em vez de toda a chave. A regra 2NF garante que todos os atributos não chave dependam da chave primária inteira, não apenas de uma parte dela. Deixar dependências parciais em uma tabela significa que dados redundantes podem se infiltrar no banco de dados, levando a ineficiências e possíveis inconsistências durante atualizações ou exclusões.
A teoria sozinha pode ser um pouco seca, então vamos ver um exemplo prático.
Abaixo está uma tabela de Matrícula em Cursos de estudantes da Datacamp.
Student ID | Course ID | Course Name | Instructor Name |
---|---|---|---|
1001 | 201 | Fundamentos de SQL | Ken Smith |
1002 | 202 | Introdução ao Python | Merlin O’Donnell |
1001 | 202 | Introdução ao Python | Merlin O’Donnell |
Aqui, a chave primária é o composto de ID do Aluno e ID do Curso. No entanto, os atributos não primos Nome do Curso e Taxa do Curso dependem apenas do ID do Curso, não da chave inteira. Isso viola a 2NF.
Passos para Decompor Tabelas para Alcançar a 2NF
Para garantir que uma tabela siga as regras da 2NF, você precisa:
- Identificar Todas as Chaves Candidatas: Determinar os conjuntos mínimos de atributos que identificam de forma única as linhas na tabela. Estes são as suas chaves candidatas.
- Determinar Dependências Funcionais: Identificar todas as dependências funcionais na tabela. Especificamente, procure por dependências onde atributos não primos (aqueles que não fazem parte de nenhuma chave candidata) dependem apenas de uma parte de uma chave composta.
- Eliminar Dependências Parciais: Para cada dependência parcial:
- Mova os atributos dependentes para uma nova tabela juntamente com a parte da chave na qual eles dependem.
- Assegure que a nova tabela tenha uma chave primária única.
- Repita Até Não Restarem Dependências Parciais: Confirme que todo atributo não primo em todas as tabelas é totalmente dependente de sua respectiva chave primária.
Exemplos da Segunda Forma Normal na Prática
Vamos agora ver dois exemplos.
Exemplo 1: Tabela de matrícula de cursos
Anteriormente, vimos a seguinte tabela de matrículas do curso:
Student ID | Course ID | Course Name | Instructor Name |
---|---|---|---|
1001 | 201 | Fundamentos de SQL | Ken Smith |
1002 | 202 | Introdução ao Python | Merlin O’Donnell |
1001 | 202 | Introdução ao Python | Merlin O’Donnell |
Vamos seguir os passos que delineamos na seção anterior.
1. Identificar nossa chave candidata.
Neste caso, a chave candidata é uma chave composta de ID do Aluno e ID do Curso. Esta combinação única identifica cada linha na tabela.
2. Determinar nossas dependências funcionais
Nome do Curso e Nome do Instrutor dependem de ID do Curso, não da chave composta completa (ID do Estudante, ID do Curso). Esta é uma dependência parcial porque esses atributos dependem apenas de parte da chave composta.
3. Elimine dependências parciais
Precisamos mover os atributos que dependem apenas de parte da chave (Nome do Curso e Nome do Instrutor) para uma nova tabela que seja baseada exclusivamente em ID do Curso.
Após a decomposição, nossas novas tabelas ficam assim:
Tabela de matrícula do curso
Student ID | Course ID |
---|---|
1001 | 201 |
1002 | 202 |
1001 | 202 |
Tabela de detalhes do curso
Course ID | Course Name | Instructor Name |
---|---|---|
201 | Fundamentos de SQL | Ken Smith |
202 | Introdução ao Python | Merlin O’Donnell |
Se você deseja colocar a mão na massa e criar seus próprios bancos de dados, dê uma olhada no nosso curso de PostgresQL. Se você é um pouco mais avançado, pode experimentar esta Introdução à Modelagem de Dados no Snowflake, que abrange ideias como modelagem entidade-relacionamento e dimensional.
Exemplo 2: Tabela de pedidos
Vamos começar com esta tabela de Pedidos. Tente seguir os passos que delineamos acima e decomponha esta tabela você mesmo!
Order ID | Product ID | Order Date | Product Name | Supplier Name |
---|---|---|---|---|
1 | 201 | 2024-11-01 | Computador Portátil | TechSupply |
1 | 202 | 2024-11-01 | Rato | TechSupply |
2 | 201 | 2024-11-02 | Computador Portátil | TechSupply |
3 | 203 | 2024-11-03 | Teclado | KeyMasters |
1. Identificar a nossa chave candidata
O ID do Pedido e ID do Produto em combinação identifica exclusivamente cada linha, tornando (ID do Pedido, ID do Produto) uma chave candidata composta. Nenhuma coluna única pode identificar linhas exclusivamente porque:
- ID do Pedido por si só não é único, pois vários produtos podem fazer parte do mesmo pedido.
- ID do Produto por si só não é único, pois o mesmo produto pode aparecer em diferentes pedidos.
Isso significa que (ID do Pedido, ID do Produto) também é nossa chave primária.
2. Determine nossas dependências funcionais.
Data do Pedido depende de ID do Pedido (não da chave composta completa). Esta é uma dependência parcial.
Nome do Produto e Nome do Fornecedor dependem de ID do Produto (não do chave primária completa). Essas são dependências parciais.
3. Eliminar dependências parciais
Precisamos dividir a tabela em tabelas menores, cada uma tratando de uma dependência lógica.
Primeiro, vamos criar uma tabela para informações de pedidos, que contém informações específicas sobre ID do Pedido.
Tabela de Pedidos
Order ID | Order Date |
---|---|
1 | 2024-11-01 |
2 | 2024-11-02 |
3 | 2024-11-03 |
Em seguida, criamos uma tabela que contém informações específicas sobre ID do Produto.
Tabela de Pedidos
Product ID | Product Name | Supplier Name |
---|---|---|
201 | Laptop | TechSupply |
202 | Mouse | TechSupply |
203 | Teclado | KeyMasters |
A tabela original agora foi reduzida apenas para a chave composta e os relacionamentos entre pedidos e produtos.
Order ID | Product ID |
---|---|
1 | 201 |
1 | 202 |
2 | 201 |
3 | 203 |
Agora, nosso banco de dados está na 2NF porque 1) todas as dependências parciais foram eliminadas e 2) as atributos não primos dependem inteiramente de suas respectivas chaves primárias.
Quando Implementar a Segunda Forma Normal
Então, por que você deve refatorar seu banco de dados para a 2NF? É suficiente por si só ou você deve dar um passo adiante e visar a 3NF?
Benefícios e limitações da segunda forma normal
A segunda forma normal oferece várias vantagens, tornando-a um passo útil no processo de normalização do banco de dados:
- Integridade de dados aprimorada: Ao eliminar dependências parciais, a 2NF minimiza anomalias de inserção, atualização e exclusão, resultando em um banco de dados mais confiável.
- Redução de redundância: A 2NF diminui a repetição de dados, otimizando o uso de armazenamento e simplificando a manutenção de dados.
- Estrutura de dados melhorada: Ela prepara o terreno para uma normalização adicional, como a progressão para a terceira forma normal, criando um design de banco de dados mais limpo e eficiente.
Mas ela vem com algumas limitações:
- Complexidade aumentada: Decompor tabelas para atender à 2NF pode tornar o processo de design mais complexo, especialmente ao lidar com chaves compostas e dependências.
- Joins adicionais: Dividir tabelas pode exigir mais joins em consultas, potencialmente impactando o desempenho em sistemas com grandes conjuntos de dados ou consultas complexas – mais detalhes abaixo.
- Redundância residual: Enquanto a 2NF reduz dependências parciais, ela não aborda dependências transitivas, deixando alguma redundância até ser abordada na 3NF.
Considerações de desempenho com a segunda forma normal
Decompor tabelas para eliminar dependências parciais pode impactar diretamente o desempenho do banco de dados. Por um lado, alcançar a 2NF reduz a redundância de dados e melhora a consistência, levando a menos anomalias durante operações de inserção, atualização ou exclusão. Por outro lado, a normalização pode aumentar o número de tabelas, o que significa que junções adicionais são necessárias ao recuperar dados relacionados. Isso pode impactar o desempenho de consultas em grandes conjuntos de dados.
Para garantir que seu banco de dados normalizado permaneça eficiente, siga estas melhores práticas:
- Indexação: Use índices para acelerar junções entre tabelas decompostas.
- Otimização de consultas: Otimize consultas para minimizar o custo de junções adicionais.
- Abordagem híbrida: Combine a normalização com a desnormalização em áreas onde o desempenho é importante, como em tabelas de relatórios.
- Monitoramento regular: Avalie continuamente o desempenho do seu banco de dados com ferramentas de perfilamento para identificar possíveis problemas.
A 2NF é apenas um passo transitório para atingir a terceira forma normal?
Na maioria dos casos, os designers de banco de dados procuram alcançar a terceira forma normal devido à sua capacidade de reduzir ainda mais a redundância e melhorar a integridade geral dos dados. No entanto, alcançar a 3NF frequentemente envolve trabalho adicional, como a criação de mais tabelas e relacionamentos, o que pode introduzir complexidade e compensações de desempenho na execução de consultas.
Há casos em que o uso da segunda forma normal por si só pode ser suficiente. Se a simplicidade e a implementação rápida forem prioridades, como em projetos de pequena escala, prototipagem ou situações em que a redundância de dados é mínima, a 2NF pode ser suficiente. Por exemplo, em sistemas onde todos os atributos já são totalmente dependentes de uma chave primária simples, alcançar a 2NF pode atender ao objetivo principal de reduzir a dependência parcial, sem a necessidade de normalização adicional.
Indo além da segunda forma normal: em direção à terceira forma normal
Se você deseja normalizar ainda mais seu banco de dados, pode continuar refatorando suas tabelas para alcançar a terceira forma normal.
3NF constrói sobre o 2NF ao abordar as dependências transitivas – situações em que atributos não chave dependem de outros atributos não chave em vez da chave primária. Esta progressão garante que cada atributo seja diretamente dependente da chave primária e de mais nada.
Por exemplo, em uma tabela que rastreia inscrições em cursos:
- 2NF: Garante que atributos como o nome do curso e o nome do estudante dependam inteiramente de suas respectivas chaves primárias (por exemplo, ID do Estudante e ID do Curso). Isso elimina dependências parciais, onde atributos não-chave dependem apenas de parte da chave composta.
- 3NF: Garante que atributos como detalhes do instrutor ou informações do departamento sejam armazenados em tabelas separadas, eliminando dependências transitivas.
O 3NF é ideal para sistemas mais complexos nos quais a integridade e eficiência dos dados são primordiais, especialmente à medida que o volume de dados cresce. Confira nosso artigo O que é a terceira forma normal? se você deseja aprender mais sobre o 3NF e sua forma mais restritiva, BCNF.
Conclusão
A segunda forma normal é um passo essencial na normalização de banco de dados, preenchendo a lacuna entre a 1NF e formas superiores como o 3NF. Ao remover dependências parciais, o 2NF reduz a redundância e melhora a confiabilidade de seus dados. Embora possa adicionar alguma complexidade, os benefícios da melhoria da integridade dos dados e da manutenção simplificada o tornam uma parte crítica do design eficaz de banco de dados.
Se você está pronto para levar suas habilidades adiante, explore nosso curso de Design de Banco de Dados para aprofundar seu entendimento das técnicas de normalização e suas aplicações práticas. Você também pode validar suas habilidades em SQL e gerenciamento de bancos de dados e demonstrar sua expertise para potenciais empregadores com nossa Certificação de Associado em SQL!
Por fim, quero dizer que se você é um tomador de decisões em um negócio e sabe que tem trabalho a fazer para criar bancos de dados mais limpos e eficientes, considere fazer uma solicitação de demonstração na DataCamp for Business. Podemos ajudar a transformar as capacidades da sua equipe para que você possa criar sistemas de banco de dados escaláveis que impulsionam a eficiência e inovação nos negócios. Podemos até mesmo criar caminhos de aprendizagem personalizados e trilhas específicas.
Source:
https://www.datacamp.com/tutorial/second-normal-form