Normalização: 1NF, 2NF e 3NF
1. Introdução à Normalização
A normalização é um processo fundamental no design de bancos de dados relacionais que visa organizar os dados de forma eficiente, reduzindo redundâncias e evitando anomalias de inserção, atualização e exclusão. Proposta por Edgar F. Codd em 1970, a normalização estabelece um conjunto de regras chamadas "formas normais" que garantem a integridade e consistência dos dados.
As três primeiras formas normais (1NF, 2NF e 3NF) são as mais utilizadas na prática e formam a base para a maioria dos projetos de banco de dados bem estruturados. Cada forma normal resolve um tipo específico de problema estrutural, partindo da eliminação de grupos repetitivos até a remoção de dependências transitivas.
2. Primeira Forma Normal (1NF)
Definição: Uma tabela está na Primeira Forma Normal quando todos os seus atributos contêm valores atômicos (indivisíveis) e não existem grupos repetitivos de colunas.
Exemplo prático: Considere uma tabela de pedidos onde um cliente pode ter múltiplos produtos em um único pedido:
-- Tabela não normalizada (viola 1NF)
CREATE TABLE pedidos (
pedido_id INT PRIMARY KEY,
cliente_nome VARCHAR(100),
cliente_telefone VARCHAR(20),
produtos VARCHAR(200), -- Múltiplos valores separados por vírgula
quantidades VARCHAR(50) -- "3,2,1" - valores não atômicos
);
Problemas:
- A coluna produtos contém múltiplos valores (viola atomicidade)
- Dificuldade em consultar produtos individuais
- Anomalias de atualização (modificar um produto exige parsing da string)
Solução para 1NF: Criar uma linha para cada produto individual:
-- Tabela em 1NF
CREATE TABLE pedidos_1nf (
pedido_id INT,
cliente_nome VARCHAR(100),
cliente_telefone VARCHAR(20),
produto VARCHAR(100),
quantidade INT,
PRIMARY KEY (pedido_id, produto)
);
-- Inserção de dados normalizados
INSERT INTO pedidos_1nf VALUES
(1, 'João Silva', '11999999999', 'Notebook', 1),
(1, 'João Silva', '11999999999', 'Mouse', 2),
(2, 'Maria Souza', '11888888888', 'Teclado', 1);
3. Segunda Forma Normal (2NF)
Pré-requisito: A tabela deve estar em 1NF.
Definição: Uma tabela está na Segunda Forma Normal quando está em 1NF e todos os atributos não chave dependem completamente da chave primária completa (eliminação de dependências funcionais parciais).
Exemplo: A tabela pedidos_1nf ainda possui dependências parciais. O cliente_nome e cliente_telefone dependem apenas do pedido_id, não do produto.
-- Tabela em 1NF com dependências parciais
-- cliente_nome depende apenas de pedido_id, não de (pedido_id, produto)
SELECT * FROM pedidos_1nf;
Processo de decomposição para 2NF:
-- Tabela de pedidos (2NF)
CREATE TABLE pedidos_2nf (
pedido_id INT PRIMARY KEY,
cliente_nome VARCHAR(100),
cliente_telefone VARCHAR(20)
);
-- Tabela de itens do pedido (2NF)
CREATE TABLE itens_pedido_2nf (
pedido_id INT,
produto VARCHAR(100),
quantidade INT,
PRIMARY KEY (pedido_id, produto),
FOREIGN KEY (pedido_id) REFERENCES pedidos_2nf(pedido_id)
);
-- Inserção nos dados normalizados
INSERT INTO pedidos_2nf VALUES
(1, 'João Silva', '11999999999'),
(2, 'Maria Souza', '11888888888');
INSERT INTO itens_pedido_2nf VALUES
(1, 'Notebook', 1),
(1, 'Mouse', 2),
(2, 'Teclado', 1);
4. Terceira Forma Normal (3NF)
Pré-requisito: A tabela deve estar em 2NF.
Definição: Uma tabela está na Terceira Forma Normal quando está em 2NF e não possui dependências funcionais transitivas (atributos não chave dependendo de outros atributos não chave).
Exemplo: Na tabela pedidos_2nf, suponha que adicionemos informações de endereço:
-- Tabela em 2NF com dependência transitiva
CREATE TABLE pedidos_2nf_transitivo (
pedido_id INT PRIMARY KEY,
cliente_nome VARCHAR(100),
cliente_telefone VARCHAR(20),
cidade VARCHAR(50),
estado VARCHAR(20) -- estado depende da cidade, não do pedido_id
);
Aqui, estado depende de cidade, que por sua vez depende de pedido_id. Isso cria uma dependência transitiva.
Solução para 3NF: Separar em tabelas de cliente e endereço:
-- Tabela de clientes (3NF)
CREATE TABLE clientes_3nf (
cliente_id INT PRIMARY KEY,
nome VARCHAR(100),
telefone VARCHAR(20),
cidade VARCHAR(50),
estado VARCHAR(20)
);
-- Tabela de pedidos (3NF)
CREATE TABLE pedidos_3nf (
pedido_id INT PRIMARY KEY,
cliente_id INT,
data_pedido DATE,
FOREIGN KEY (cliente_id) REFERENCES clientes_3nf(cliente_id)
);
-- Tabela de itens do pedido (3NF)
CREATE TABLE itens_pedido_3nf (
pedido_id INT,
produto VARCHAR(100),
quantidade INT,
PRIMARY KEY (pedido_id, produto),
FOREIGN KEY (pedido_id) REFERENCES pedidos_3nf(pedido_id)
);
-- Inserção nos dados em 3NF
INSERT INTO clientes_3nf VALUES
(1, 'João Silva', '11999999999', 'São Paulo', 'SP'),
(2, 'Maria Souza', '11888888888', 'Rio de Janeiro', 'RJ');
INSERT INTO pedidos_3nf VALUES
(1, 1, '2024-01-15'),
(2, 2, '2024-01-16');
INSERT INTO itens_pedido_3nf VALUES
(1, 'Notebook', 1),
(1, 'Mouse', 2),
(2, 'Teclado', 1);
5. Exemplo Completo Passo a Passo
Cenário inicial: Tabela de pedidos com dados misturados
-- Esquema original (não normalizado)
CREATE TABLE pedidos_original (
pedido_id INT PRIMARY KEY,
cliente_nome VARCHAR(100),
cliente_telefone VARCHAR(20),
cliente_cidade VARCHAR(50),
cliente_estado VARCHAR(20),
produtos VARCHAR(200),
quantidades VARCHAR(50),
vendedor_nome VARCHAR(100),
vendedor_regiao VARCHAR(50)
);
Aplicação sequencial das formas normais:
- 1NF: Separar produtos em linhas individuais
- 2NF: Criar tabelas separadas para pedidos e itens
- 3NF: Separar dados de cliente e vendedor
-- Esquema normalizado final (3NF)
CREATE TABLE clientes (
cliente_id INT PRIMARY KEY,
nome VARCHAR(100),
telefone VARCHAR(20),
cidade VARCHAR(50),
estado VARCHAR(20)
);
CREATE TABLE vendedores (
vendedor_id INT PRIMARY KEY,
nome VARCHAR(100),
regiao VARCHAR(50)
);
CREATE TABLE pedidos (
pedido_id INT PRIMARY KEY,
cliente_id INT,
vendedor_id INT,
data_pedido DATE,
FOREIGN KEY (cliente_id) REFERENCES clientes(cliente_id),
FOREIGN KEY (vendedor_id) REFERENCES vendedores(vendedor_id)
);
CREATE TABLE itens_pedido (
pedido_id INT,
produto VARCHAR(100),
quantidade INT,
PRIMARY KEY (pedido_id, produto),
FOREIGN KEY (pedido_id) REFERENCES pedidos(pedido_id)
);
6. Benefícios e Desvantagens da Normalização
Benefícios:
- Integridade dos dados: Reduz anomalias de inserção, atualização e exclusão
- Redução de espaço: Elimina redundâncias desnecessárias
- Facilidade de manutenção: Alterações em dados mestre (como endereço do cliente) são feitas em um único local
- Consistência: Garante que dados duplicados não fiquem inconsistentes
Desvantagens:
- Aumento de JOINs: Consultas que antes liam uma única tabela agora exigem múltiplos JOINs
- Impacto em performance de leitura: JOINs adicionais podem tornar consultas mais lentas em grandes volumes
- Complexidade: O esquema pode se tornar mais difícil de entender para iniciantes
Quando normalizar:
- Essencial para sistemas transacionais (OLTP) com muitas operações de escrita
- Pode ser flexibilizada em sistemas de análise (OLAP) ou data warehouses
7. Conclusão e Próximos Passos
A normalização 1NF, 2NF e 3NF forma a base para projetos de banco de dados relacionais robustos. A 1NF elimina grupos repetitivos, a 2NF remove dependências parciais e a 3NF elimina dependências transitivas. O resultado é um esquema que minimiza redundâncias e garante integridade referencial.
Formas normais mais avançadas como BCNF (Boyce-Codd Normal Form) e 4NF (Quarta Forma Normal) tratam de casos específicos de dependências funcionais e multivaloradas, sendo menos comuns na prática.
Nos próximos artigos desta série, abordaremos índices para otimização de consultas e técnicas de desnormalização para cenários de alta performance de leitura.
Referências
- Documentação Oficial PostgreSQL - Normalização — Guia oficial sobre design de esquemas e boas práticas de normalização
- Microsoft SQL Server - Guia de Normalização — Artigo técnico da Microsoft explicando as formas normais com exemplos práticos
- Oracle Database - Conceitos de Normalização — Documentação Oracle sobre design de banco de dados e normalização
- Tutorial SQL do W3Schools - Normalização — Tutorial interativo com exemplos práticos de 1NF, 2NF e 3NF
- Artigo da IBM sobre Normalização — Documentação técnica da IBM sobre o processo de normalização em bancos de dados