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 a 2NF é fundamental para quem trabalha com design de banco de dados ou gerenciamento de dados, e ela estabelece a base para formas de normalização mais avançadas, como a terceira forma normal (3NF). Neste artigo, exploraremos como a 2NF funciona e como transformar tabelas para atender aos requisitos da 2NF, com exemplos práticos. Também abordaremos os benefícios e desvantagens da 2NF, e os casos de uso nos quais ela 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 sobre normalização.
Antes de uma tabela poder estar na 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.
O 2NF vai um passo adiante com uma regra adicional: eliminar dependências parciais.
Uma dependência parcial ocorre quando um atributo não-prime (coluna que não faz parte de nenhuma chave candidata) depende apenas de parte de uma chave composta em vez da chave inteira. A regra da 2NF garante que todos os atributos não-prime dependam da chave primária completa, 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 potenciais inconsistências durante atualizações ou exclusões.
A teoria sozinha pode ser um pouco seca, então vamos olhar um exemplo prático.
Abaixo está uma Tabela de Matrícula em Cursos dos alunos 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 unicamente 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 junto com a parte da chave na qual eles dependem.
- Assegure-se de que a nova tabela tenha uma chave primária única.
- Repita Até que Não Haja Mais Dependências Parciais:Confirme que cada 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 analisar dois exemplos.
Exemplo 1: Tabela de matrícula de curso
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. Identifique nossa chave candidata.
Neste caso, a chave candidata é uma chave composta de ID do Aluno e ID do Curso. Essa combinação única identifica cada linha na tabela.
2. Determinar nossas dependências funcionais
Nome do Curso e Nome do Instrutor dependem do ID do Curso, não do chave composta completa (ID do Estudante, ID do Curso). Isso é uma dependência parcial porque esses atributos dependem apenas de parte da chave composta.
3. Eliminar 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 é 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 | SQL Fundamentals | 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 em nosso curso de PostgresQL. Se você está 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 destacamos acima e decomponha esta tabela por conta própria!
Order ID | Product ID | Order Date | Product Name | Supplier Name |
---|---|---|---|---|
1 | 201 | 2024-11-01 | Laptop | TechSupply |
1 | 202 | 2024-11-01 | Mouse | TechSupply |
2 | 201 | 2024-11-02 | Laptop | TechSupply |
3 | 203 | 2024-11-03 | Keyboard | KeyMasters |
1. Identifique nossa chave candidata
O ID do Pedido e a combinação do ID do Produto identificam exclusivamente cada linha, tornando (ID do Pedido, ID do Produto) uma chave candidata composta. Nenhuma coluna única pode identificar exclusivamente as linhas 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. Determinar nossas dependências funcionais
Data do Pedidodepende deID do Pedido(não do chave composta completa). Isso é uma dependência parcial.
Nome do Produto e Nome do Fornecedor dependem do ID do Produto (não na chave composta completa). Estas são também dependências parciais.
3. Eliminar dependências parciais
Precisamos dividir a tabela em tabelas menores, cada uma abordando 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 | Notebook | TechSupply |
202 | Mouse | TechSupply |
203 | Teclado | KeyMasters |
A tabela original agora foi reduzida a apenas 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á em 2NF porque 1) todas as dependências parciais foram eliminadas, e 2) atributos não primários 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, levando a 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 normalizações adicionais, 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.
- Junções adicionais: Dividir tabelas pode exigir mais junções 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 tratada na 3NF.
Considerações de desempenho com a segunda forma normal
Decompor tabelas para eliminar dependências parciais pode impactar diretamente no desempenho do banco de dados. Por um lado, atingir 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 são necessários joins adicionais ao recuperar dados relacionados. Isso pode impactar o desempenho da consulta em conjuntos de dados grandes.
Para garantir que seu banco de dados normalizado permaneça performático, siga estas melhores práticas:
- Indexação: Use índices para acelerar joins entre tabelas decompostas.
- Otimização de consulta: Otimize consultas para minimizar o custo de joins adicionais.
- Abordagem híbrida: Combine normalização com desnormalização em áreas onde o desempenho é importante, como tabelas de relatório.
- 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 alcançar 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 usar apenas a segunda forma normal 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 cumprir o objetivo principal de reduzir a dependência parcial, sem a necessidade de uma 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 atingir a terceira forma normal.
3NF se baseia na 2NF ao abordar dependências transitivas – situações em que atributos não-chave dependem de outros atributos não-chave em vez da chave primária. Essa progressão garante que cada atributo dependa diretamente da chave primária e nada mais.
Por exemplo, em uma tabela que rastreia matrículas em cursos:
- 2NF: Garante que atributos como o nome do curso e o nome do aluno dependam inteiramente de suas respectivas chaves primárias (por exemplo, ID do Aluno 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 onde a integridade e eficiência dos dados são primordiais, especialmente à medida que o volume de dados aumenta. Confira nosso artigo O que é a terceira forma normal? se 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 o 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 para o próximo nível, 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 gestão de banco de dados e demonstrar sua expertise para potenciais empregadores com nossa Certificação de Associado em SQL!
Por fim, gostaria de dizer que se você é um tomador de decisões em um negócio e sabe que precisa trabalhar na criação de bancos de dados mais limpos e eficientes, considere fazer uma solicitação de demonstração da plataforma 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 impulsionem a eficiência e inovação do negócio. Podemos até criar trajetos de aprendizagem personalizados e faixas específicas.
Source:
https://www.datacamp.com/tutorial/second-normal-form