Relacionamentos entre Tabelas
Intermediário • 60 minutos • Conceitos importantes
Entenda como conectar tabelas usando chaves estrangeiras e como isso organiza melhor seus dados, evitando duplicação e mantendo consistência.
Objetivos de Aprendizagem
- Compreender o conceito de chaves estrangeiras
- Identificar tipos de relacionamentos (1:1, 1:N, N:N)
- Criar tabelas com relacionamentos
- Entender a importância da integridade referencial
- Aplicar boas práticas de modelagem
O que são Relacionamentos?
Relacionamentos conectam dados entre diferentes tabelas, evitando repetição e mantendo a organização. É como ter gavetas organizadas em vez de tudo misturado em uma caixa.
Exemplo do mundo real:
Uma loja tem clientes e pedidos. Em vez de repetir os dados do cliente em cada pedido, criamos uma tabela de clientes e conectamos os pedidos a ela.
Problema: Dados Duplicados
❌ Tabela mal projetada (com duplicação):
| pedido_id | cliente_nome | cliente_email | cliente_telefone | produto |
|---|---|---|---|---|
| 1 | João Silva | joao@email.com | (11) 99999-9999 | Notebook |
| 2 | João Silva | joao@email.com | (11) 99999-9999 | Mouse |
Problemas: dados repetidos, desperdício de espaço, difícil de manter
Solução: Tabelas Relacionadas
✅ Design correto (com relacionamento):
Tabela: clientes
| id | nome | |
|---|---|---|
| 1 | João Silva | joao@email.com |
Tabela: pedidos
| id | cliente_id | produto |
|---|---|---|
| 1 | 1 | Notebook |
| 2 | 1 | Mouse |
Vantagens: sem duplicação, fácil manutenção, dados consistentes
Chaves Estrangeiras (Foreign Keys)
Uma chave estrangeira é uma coluna que aponta para a chave primária de outra tabela. É como um "endereço" que diz onde encontrar informações relacionadas.
Conceitos importantes:
- Chave Primária (PK): Identifica unicamente cada registro
- Chave Estrangeira (FK): Referencia a PK de outra tabela
- Integridade Referencial: Garante que as referências sejam válidas
Criando uma Chave Estrangeira
-- Primeiro, criar a tabela "pai" (clientes)
CREATE TABLE clientes (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
telefone VARCHAR(20)
);
-- Depois, criar a tabela "filha" (pedidos)
CREATE TABLE pedidos (
id SERIAL PRIMARY KEY,
cliente_id INTEGER NOT NULL,
produto VARCHAR(100) NOT NULL,
quantidade INTEGER DEFAULT 1,
data_pedido TIMESTAMP DEFAULT NOW(),
-- Definir a chave estrangeira
FOREIGN KEY (cliente_id) REFERENCES clientes(id)
);
🔗 Como funciona:
- •
cliente_idna tabela pedidos - • Aponta para
idna tabela clientes - • Garante que o cliente existe
- • Impede exclusão de clientes com pedidos
⚠️ Regras importantes:
- • FK deve referenciar uma PK existente
- • Não pode inserir FK inexistente
- • Não pode deletar PK referenciada
- • Mantém consistência dos dados
Tipos de Relacionamentos
Existem três tipos principais de relacionamentos entre tabelas. Cada um serve para situações diferentes.
Um para Um (1:1)
Cada registro de uma tabela se relaciona com exatamente um registro de outra tabela.
Exemplo: Usuário ↔ Perfil
Cada usuário tem exatamente um perfil, e cada perfil pertence a exatamente um usuário.
CREATE TABLE usuarios (
id SERIAL PRIMARY KEY,
email VARCHAR(100) UNIQUE NOT NULL
);
CREATE TABLE perfis (
id SERIAL PRIMARY KEY,
usuario_id INTEGER UNIQUE NOT NULL,
nome_completo VARCHAR(200),
bio TEXT,
FOREIGN KEY (usuario_id) REFERENCES usuarios(id)
);
Um para Muitos (1:N)
Um registro de uma tabela pode se relacionar com vários registros de outra tabela.
Exemplo: Cliente → Pedidos
Um cliente pode ter vários pedidos, mas cada pedido pertence a apenas um cliente.
CREATE TABLE clientes (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL
);
CREATE TABLE pedidos (
id SERIAL PRIMARY KEY,
cliente_id INTEGER NOT NULL,
total DECIMAL(10,2),
FOREIGN KEY (cliente_id) REFERENCES clientes(id)
);
Muitos para Muitos (N:N)
Vários registros de uma tabela podem se relacionar com vários registros de outra tabela.
Exemplo: Produtos ↔ Categorias
Um produto pode ter várias categorias, e uma categoria pode ter vários produtos.
CREATE TABLE produtos (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL
);
CREATE TABLE categorias (
id SERIAL PRIMARY KEY,
nome VARCHAR(50) NOT NULL
);
-- Tabela de junção (junction table)
CREATE TABLE produto_categorias (
produto_id INTEGER NOT NULL,
categoria_id INTEGER NOT NULL,
PRIMARY KEY (produto_id, categoria_id),
FOREIGN KEY (produto_id) REFERENCES produtos(id),
FOREIGN KEY (categoria_id) REFERENCES categorias(id)
);
Nota: Relacionamentos N:N precisam de uma tabela intermediária (tabela de junção) para funcionar.
Exemplo Prático: Sistema de E-commerce
Vamos criar um sistema simples de e-commerce para entender como os relacionamentos funcionam na prática.
-- 1. Tabela de categorias
CREATE TABLE categorias (
id SERIAL PRIMARY KEY,
nome VARCHAR(50) NOT NULL UNIQUE,
descricao TEXT
);
-- 2. Tabela de produtos (relacionamento 1:N com categorias)
CREATE TABLE produtos (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
preco DECIMAL(10,2) NOT NULL,
categoria_id INTEGER NOT NULL,
em_estoque BOOLEAN DEFAULT true,
FOREIGN KEY (categoria_id) REFERENCES categorias(id)
);
-- 3. Tabela de clientes
CREATE TABLE clientes (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
telefone VARCHAR(20)
);
-- 4. Tabela de pedidos (relacionamento 1:N com clientes)
CREATE TABLE pedidos (
id SERIAL PRIMARY KEY,
cliente_id INTEGER NOT NULL,
data_pedido TIMESTAMP DEFAULT NOW(),
status VARCHAR(20) DEFAULT 'pendente',
total DECIMAL(10,2),
FOREIGN KEY (cliente_id) REFERENCES clientes(id)
);
-- 5. Tabela de itens do pedido (relacionamento N:N entre pedidos e produtos)
CREATE TABLE itens_pedido (
id SERIAL PRIMARY KEY,
pedido_id INTEGER NOT NULL,
produto_id INTEGER NOT NULL,
quantidade INTEGER NOT NULL DEFAULT 1,
preco_unitario DECIMAL(10,2) NOT NULL,
FOREIGN KEY (pedido_id) REFERENCES pedidos(id),
FOREIGN KEY (produto_id) REFERENCES produtos(id)
);
Inserindo Dados com Relacionamentos
-- Inserir categorias primeiro
INSERT INTO categorias (nome, descricao) VALUES
('Eletrônicos', 'Produtos eletrônicos e gadgets'),
('Casa', 'Produtos para casa e decoração');
-- Inserir produtos (referenciando categorias)
INSERT INTO produtos (nome, preco, categoria_id) VALUES
('Smartphone', 899.99, 1), -- categoria_id 1 = Eletrônicos
('Notebook', 2499.99, 1), -- categoria_id 1 = Eletrônicos
('Sofá', 1299.99, 2); -- categoria_id 2 = Casa
-- Inserir cliente
INSERT INTO clientes (nome, email, telefone) VALUES
('Maria Silva', 'maria@email.com', '(11) 98765-4321');
-- Criar pedido
INSERT INTO pedidos (cliente_id, total) VALUES
(1, 3399.98); -- cliente_id 1 = Maria Silva
-- Adicionar itens ao pedido
INSERT INTO itens_pedido (pedido_id, produto_id, quantidade, preco_unitario) VALUES
(1, 1, 1, 899.99), -- 1 Smartphone
(1, 2, 1, 2499.99); -- 1 Notebook
🎯 Ordem de inserção importante:
- 1. Primeiro as tabelas "pai" (categorias, clientes)
- 2. Depois as tabelas "filha" (produtos, pedidos)
- 3. Por último as tabelas de junção (itens_pedido)
Exercício Prático
Vamos praticar relacionamentos!
Complete o design de um sistema de biblioteca:
1. Que tipo de relacionamento existe entre "Autor" e "Livro"?
Um autor pode escrever vários livros, mas cada livro tem apenas um autor principal.
2. Complete a criação da tabela "livros":
CREATE TABLE livros (
id SERIAL PRIMARY KEY,
titulo VARCHAR(200) NOT NULL,
autor_id INTEGER NOT NULL,
ano_publicacao INTEGER,
FOREIGN KEY (autor_id) _______ _______(id)
);
3. Que tipo de relacionamento existe entre "Livro" e "Categoria"?
Um livro pode pertencer a várias categorias (ficção, romance, aventura), e uma categoria pode ter vários livros.
4. Para um relacionamento N:N, precisamos de:
Boas Práticas
✅ Faça assim
- • Use nomes descritivos para FKs (cliente_id, produto_id)
- • Sempre defina NOT NULL em FKs obrigatórias
- • Crie índices em colunas de FK para performance
- • Documente os relacionamentos
- • Use SERIAL para chaves primárias
💡 Dicas
- • Desenhe o diagrama antes de criar as tabelas
- • Comece pelas tabelas "pai" (sem dependências)
- • Teste a inserção de dados para validar o design
- • Use ferramentas visuais para modelagem
❌ Evite
- • FKs com nomes genéricos (id, fk1, ref)
- • Relacionamentos circulares desnecessários
- • Muitas tabelas de junção
- • FKs opcionais sem justificativa
- • Duplicação de dados entre tabelas
⚠️ Cuidados
- • FKs podem impedir exclusões
- • Relacionamentos afetam performance
- • Ordem de inserção/exclusão importa
- • Mudanças de schema são mais complexas
Resumo da Aula
- Relacionamentos conectam tabelas e evitam duplicação de dados
- Chaves estrangeiras garantem integridade referencial
- Existem três tipos: 1:1, 1:N e N:N
- Relacionamentos N:N precisam de tabela intermediária
- A ordem de criação e inserção de dados é importante