Entenda como dados sao organizados em tabelas, como garantir integridade e como modelar antes de escrever uma linha de SQL.
O modelo relacional e a base de praticamente todos os bancos de dados que voce vai usar na carreira. Criado por Edgar F. Codd na IBM em 1970, ele organiza dados em tabelas (chamadas de relacoes) com linhas e colunas bem definidas. Cada tabela representa uma entidade do mundo real.
cliente, pedidoPense em uma tabela como uma planilha Excel, mas com regras rigidas: cada coluna tem um tipo, cada linha e unica, e a ordem das linhas nao importa. A grande diferenca e que no banco relacional, as regras sao impostas pelo sistema, nao pela disciplina do usuario.
-- Exemplo: tabela cliente
-- Cada linha = um cliente, cada coluna = um atributo
CREATE TABLE cliente (
id SERIAL PRIMARY KEY, -- Coluna: identificador unico
nome TEXT NOT NULL, -- Coluna: nome obrigatorio
email TEXT UNIQUE -- Coluna: email unico
);
-- Inserindo uma "tupla" (linha/registro)
INSERT INTO cliente (nome, email)
VALUES ('Ana Silva', 'ana@email.com');
Chaves sao o mecanismo que da identidade aos registros e conecta tabelas entre si. A chave primaria (PK) garante que cada registro e unico. A chave estrangeira (FK) cria um vinculo entre tabelas, referenciando a PK de outra tabela.
-- PK: identifica o cliente
CREATE TABLE cliente (
id SERIAL PRIMARY KEY,
nome TEXT NOT NULL,
email TEXT UNIQUE
);
-- FK: conecta pedido ao cliente
CREATE TABLE pedido (
id SERIAL PRIMARY KEY,
cliente_id INT NOT NULL REFERENCES cliente(id)
ON DELETE CASCADE,
total NUMERIC(10,2) NOT NULL,
criado_em TIMESTAMP DEFAULT NOW()
);
-- Tentativa de inserir pedido com cliente inexistente:
-- INSERT INTO pedido (cliente_id, total) VALUES (999, 50.00);
-- ERRO: violacao de chave estrangeira!
Restricoes sao regras declarativas no schema que impedem dados invalidos de entrar no banco. Sao a ultima linha de defesa da integridade, mesmo que a aplicacao tenha bugs. O banco recusa dados que violam as restricoes.
CHECK (idade >= 0)A boa pratica e validar em multiplas camadas: frontend (UX rapida), backend (regras de negocio), e banco (ultima defesa). Nunca confie apenas na validacao do frontend. O banco e a unica camada que voce controla 100%.
CREATE TABLE produto (
id SERIAL PRIMARY KEY,
nome TEXT NOT NULL, -- obrigatorio
sku TEXT UNIQUE NOT NULL, -- unico e obrigatorio
preco NUMERIC(10,2) NOT NULL
CHECK (preco > 0), -- deve ser positivo
estoque INT NOT NULL DEFAULT 0
CHECK (estoque >= 0), -- nao pode ser negativo
ativo BOOLEAN DEFAULT true -- padrao: ativo
);
-- Tentativas que o banco REJEITA:
-- INSERT INTO produto (nome, sku, preco) VALUES ('X', 'ABC', -10);
-- ERRO: violacao de CHECK (preco > 0)
-- INSERT INTO produto (sku, preco) VALUES ('DEF', 25.00);
-- ERRO: violacao de NOT NULL (nome)
Normalizacao e o processo de reorganizar tabelas para eliminar redundancia e evitar anomalias. Segue etapas progressivas chamadas formas normais. Na pratica, chegar ate a 3FN resolve a maioria dos problemas.
telefones: "11-9999, 11-8888", crie uma tabela telefone separada.
Tabelas nao normalizadas causam tres tipos de anomalia: insercao (nao consigo inserir um dado sem outro), atualizacao (preciso atualizar em N lugares) e exclusao (perco dados que nao queria). Normalizacao elimina as tres.
-- ANTES (nao normalizado, violando 1FN):
-- | id | nome | telefones |
-- | 1 | Ana | 11-9999, 11-8888 | <- lista em uma celula!
-- DEPOIS (normalizado, 1FN):
CREATE TABLE cliente (
id SERIAL PRIMARY KEY,
nome TEXT NOT NULL
);
CREATE TABLE telefone (
id SERIAL PRIMARY KEY,
cliente_id INT REFERENCES cliente(id),
numero TEXT NOT NULL
);
-- Cada telefone e um registro separado
INSERT INTO telefone (cliente_id, numero) VALUES (1, '11-9999');
INSERT INTO telefone (cliente_id, numero) VALUES (1, '11-8888');
Antes de escrever SQL, voce modela. O Diagrama Entidade-Relacionamento (ER) e a planta do banco de dados. Ele mostra quais entidades existem, quais atributos cada uma tem e como elas se relacionam.
1:1 - Um para um (pessoa e CPF)1:N - Um para muitos (cliente e pedidos)N:N - Muitos para muitos (aluno e disciplina, precisa tabela intermediaria)Sempre modele antes de criar tabelas. Use ferramentas como dbdiagram.io, draw.io ou ate papel e caneta. Um bom diagrama ER economiza horas de refatoracao. Lembre: relacionamento N:N sempre precisa de uma tabela associativa (tabela ponte).
-- Exemplo de N:N: aluno cursa disciplina
-- Precisa de tabela associativa "matricula"
CREATE TABLE aluno (
id SERIAL PRIMARY KEY,
nome TEXT NOT NULL
);
CREATE TABLE disciplina (
id SERIAL PRIMARY KEY,
nome TEXT NOT NULL
);
-- Tabela ponte (resolve o N:N)
CREATE TABLE matricula (
aluno_id INT REFERENCES aluno(id),
disciplina_id INT REFERENCES disciplina(id),
semestre TEXT NOT NULL,
PRIMARY KEY (aluno_id, disciplina_id, semestre)
);
Banco relacional nao e a resposta para tudo. Saber quando usar e quando nao usar e tao importante quanto saber SQL. A escolha certa depende da natureza dos dados e dos requisitos do sistema.
Na duvida, comece com relacional. PostgreSQL e MySQL cobrem 80% dos casos de uso. So migre para NoSQL quando tiver um problema real de escala ou formato que o relacional nao resolve bem. "Premature optimization is the root of all evil."