Fundamentos de Banco de Dados
Um banco de dados é um sistema organizado para armazenar, recuperar e gerenciar dados de forma eficiente. Ele resolve um problema fundamental: guardar informações de maneira estruturada, permitindo acesso rápido sem perder integridade. Existem dois paradigmas principais: relacionais (SQL) e não-relacionais (NoSQL). Bancos relacionais usam tabelas com linhas e colunas, enquanto NoSQL oferece flexibilidade com documentos, chave-valor ou grafos.
Por que Aprender Banco de Dados?
A maioria das aplicações modernas depende de dados. Saber projetar um banco de dados eficiente impacta diretamente no desempenho da aplicação, custo de infraestrutura e experiência do usuário. Um desenvolvedor competente compreende normalização, indexação e otimização de queries — essas habilidades o diferencia no mercado.
SQL: A Linguagem Universal de Dados
SQL (Structured Query Language) é o padrão para bancos de dados relacionais. Ela permite criar tabelas, inserir dados, recuperar informações e manter a integridade dos registros através de constraints e relacionamentos.
Operações CRUD e Queries Essenciais
CREATE, READ, UPDATE e DELETE são as operações básicas. Vamos a um exemplo prático com um banco de uma livraria:
-- Criar tabela
CREATE TABLE livros (
id INT PRIMARY KEY AUTO_INCREMENT,
titulo VARCHAR(255) NOT NULL,
autor VARCHAR(255) NOT NULL,
ano_publicacao INT,
preco DECIMAL(10, 2),
categoria_id INT,
FOREIGN KEY (categoria_id) REFERENCES categorias(id)
);
-- Inserir dados
INSERT INTO livros (titulo, autor, ano_publicacao, preco, categoria_id)
VALUES ('1984', 'George Orwell', 1949, 45.90, 1);
-- Ler dados com filtro
SELECT titulo, autor, preco
FROM livros
WHERE ano_publicacao > 1950
ORDER BY preco DESC;
-- Atualizar registro
UPDATE livros
SET preco = 39.90
WHERE id = 1;
-- Deletar registro
DELETE FROM livros
WHERE id = 1;
JOINs e Relacionamentos
Dados raramente existem isolados. JOINs combinam dados de múltiplas tabelas. Uma livraria precisa relacionar livros com autores, categorias e estoques:
-- INNER JOIN: retorna apenas correspondências
SELECT l.titulo, c.nome AS categoria, a.nome AS autor
FROM livros l
INNER JOIN categorias c ON l.categoria_id = c.id
INNER JOIN autores a ON l.autor_id = a.id
WHERE c.nome = 'Ficção Científica';
-- LEFT JOIN: mantém todos os livros, mesmo sem categoria
SELECT l.titulo, c.nome
FROM livros l
LEFT JOIN categorias c ON l.categoria_id = c.id;
Normalização e Design Eficiente
Normalização é o processo de estruturar um banco de dados para eliminar redundância e melhorar integridade. Ela segue formas normais (1NF, 2NF, 3NF), cada uma com regras específicas.
Primeira e Segunda Forma Normal
A 1NF exige que cada coluna contenha valores atômicos (indivisíveis). A 2NF elimina dependências parciais — toda coluna não-chave deve depender integralmente da chave primária. Exemplo:
-- ❌ ERRADO (viola 1NF)
CREATE TABLE pedidos_ruim (
id INT PRIMARY KEY,
produtos VARCHAR(500), -- múltiplos produtos em um campo
quantidade VARCHAR(500)
);
-- ✅ CORRETO (1NF e 2NF)
CREATE TABLE pedidos (
id INT PRIMARY KEY,
cliente_id INT,
data_pedido DATE,
FOREIGN KEY (cliente_id) REFERENCES clientes(id)
);
CREATE TABLE itens_pedido (
pedido_id INT,
produto_id INT,
quantidade INT,
preco_unitario DECIMAL(10, 2),
PRIMARY KEY (pedido_id, produto_id),
FOREIGN KEY (pedido_id) REFERENCES pedidos(id),
FOREIGN KEY (produto_id) REFERENCES produtos(id)
);
A 3NF vai além: nenhuma coluna não-chave deve depender de outra coluna não-chave. Isso previne anomalias de atualização e mantém o banco coeso.
Performance e Otimização
Um banco de dados bem estruturado não é suficiente; é preciso otimizar queries. Índices, execução de planos e monitoramento são habilidades críticas em produção.
Índices e Análise de Planos de Execução
Índices funcionam como catálogos em um livro — permitem buscar informações rapidamente sem escanear toda a tabela:
-- Criar índices em colunas frequentemente buscadas
CREATE INDEX idx_autor ON livros(autor);
CREATE INDEX idx_categoria ON livros(categoria_id);
-- Analisar plano de execução (MySQL/PostgreSQL)
EXPLAIN SELECT * FROM livros WHERE autor = 'Orwell';
-- Índices compostos para queries comuns
CREATE INDEX idx_categoria_ano ON livros(categoria_id, ano_publicacao);
-- Query que se beneficia do índice composto
SELECT titulo FROM livros
WHERE categoria_id = 1 AND ano_publicacao > 2000;
Boas Práticas em Produção
Evite N+1 queries (múltiplas queries onde uma seria suficiente), use LIMIT em buscas grandes, e implemente cache para dados frequentemente consultados. Monitore slow queries com ferramentas como MySQL Workbench ou pg_stat_statements no PostgreSQL.
-- ❌ N+1: loop em aplicação consulta cada livro
-- SELECT * FROM categorias;
-- (depois, para cada categoria, SELECT * FROM livros WHERE categoria_id = ?)
-- ✅ Uma única query eficiente
SELECT c.nome, COUNT(l.id) as total_livros
FROM categorias c
LEFT JOIN livros l ON c.id = l.categoria_id
GROUP BY c.id
HAVING total_livros > 0;
Conclusão
Dominar banco de dados exige compreensão em três pilares: estrutura lógica (normalização e design), linguagem prática (SQL e queries otimizadas) e performance (índices, planos e monitoramento). Comece dominando o SQL fundamentalmente, depois aprenda a pensar em termos de dados — quais informações relacionadas, como evitar redundância, onde as buscas serão lentas. Com essas habilidades, você estará preparado não apenas para bancos relacionais, mas também terá ferramentas mentais para compreender NoSQL e outras tecnologias.