Seja bem-vindo a uma das aulas mais importantes do nosso curso! Hoje a gente vai trocar uma ideia sobre como criar foreign keys no PostgreSQL. Esse assunto é chave no design de banco de dados, porque são justamente as foreign keys que deixam a gente conectar tabelas diferentes. Se você acha que vai se perder no seu futuro "SQL-cidade", imagina as foreign keys como pontes ligando bairros diferentes.
Falando de um jeito simples, uma foreign key é uma coluna (ou um grupo de colunas) numa tabela que aponta pra uma coluna (geralmente a primary key) de outra tabela.
Por exemplo, se você tem duas tabelas — students (alunos) e courses (cursos), uma foreign key na tabela courses pode "apontar" pra qual aluno tá matriculado no curso. Assim, rola uma ligação entre essas tabelas.
Por que isso é importante?
- A foreign key ajuda a garantir a integridade dos dados: não dá pra inserir algo numa tabela se isso não existe na outra.
- Elas facilitam a vida na hora de mexer com os dados. Por exemplo, quando você apaga um registro numa tabela, dá pra configurar pra apagar automaticamente os registros relacionados na outra.
Sintaxe pra criar uma foreign key
Criar uma foreign key no PostgreSQL é moleza — só precisa de um pouco de mágica SQL. Olha a sintaxe básica:
CREATE TABLE tabela_dependente (
coluna_foreign_id DATA_TYPE REFERENCES tabela_pai(coluna_id)
);
Bora mergulhar nos detalhes e ver uns exemplos na prática.
Exemplo 1: Tabelas students e courses
Imagina que a gente quer criar uma ligação entre alunos e cursos. Cada curso tem que estar ligado a algum aluno. Pra isso, é só rodar esse comando:
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
student_id INT REFERENCES students(student_id)
);
Aqui:
- Na tabela
studentsa gente criou a primary keyPRIMARY KEYpra identificar cada aluno. - Na tabela
coursesa colunastudent_idé a foreign keyFOREIGN KEY, que aponta pra colunastudent_idna tabelastudents.
Tabela students
| student_id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
Tabela courses
| course_id | title | student_id - FOREIGN KEY |
|---|---|---|
| 1 | SQL Basics | 1 |
| 2 | Algorithms | 1 |
| 3 | Data Structures | 2 |
| 4 | Intro to Python | 3 |
Observação importante
Quando você adiciona uma foreign key, o PostgreSQL automaticamente cria uma regra que checa se os valores da foreign key batem com valores que já existem na tabela indicada. Se você tentar inserir um valor errado, o banco vai dar erro.
Aplicação prática: modelo students, courses e enrollments
Bora ver um exemplo mais cabuloso com relação "muitos-para-muitos". Os mesmos alunos podem se matricular em vários cursos, e um curso pode ter vários alunos. Pra fazer esse tipo de ligação, a gente precisa de uma tabela intermediária.
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL
);
CREATE TABLE enrollments (
enrollment_id SERIAL PRIMARY KEY,
student_id INT REFERENCES students(student_id), -- foreign key
course_id INT REFERENCES courses(course_id) -- foreign key
);
Aqui a tabela enrollments conecta as tabelas students e courses usando as foreign keys student_id e course_id.
Inserindo dados
-- Adicionando alunos
INSERT INTO students (name) VALUES ('Ivan Ivanov'), ('Maria Smirnova');
-- Adicionando cursos
INSERT INTO courses (title) VALUES ('Matematika'), ('Fizika');
-- Matriculando alunos nos cursos
INSERT INTO enrollments (student_id, course_id) VALUES (1, 1), (1, 2), (2, 1);
Selecionando dados
Agora dá pra fazer consultas de boa pra saber em quais cursos um aluno tá ou quais alunos estão em um curso específico:
-- Cursos em que Ivan Ivanov tá matriculado
SELECT c.title
FROM enrollments e
JOIN courses c ON e.course_id = c.course_id
WHERE e.student_id = 1;
-- Alunos matriculados no curso "Matematika"
SELECT s.name
FROM enrollments e
JOIN students s ON e.student_id = s.student_id
WHERE e.course_id = 1;
Recursos avançados: ON DELETE e ON UPDATE
A foreign key também precisa controlar o que rola quando você muda ou apaga registros na tabela pai. Pra isso, a gente usa os modificadores ON DELETE e ON UPDATE. Olha as opções principais:
- CASCADE: mudanças ou deleções na tabela pai são aplicadas automaticamente nos registros filhos.
- SET NULL: os valores da foreign key na tabela filha viram
NULL. - RESTRICT: não deixa apagar ou mudar dados se eles já estão sendo usados na tabela filha.
- NO ACTION: basicamente igual ao
RESTRICT, mas a checagem rola depois.
Exemplo 2: Usando ON DELETE CASCADE
Imagina que a gente quer que, ao apagar um aluno da tabela students, todos os cursos dele na tabela courses sejam apagados automaticamente. É assim que faz:
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
student_id INT REFERENCES students(student_id) ON DELETE CASCADE
);
Agora, se você apagar um aluno da tabela students, todos os registros relacionados a esse aluno na tabela courses também vão ser apagados. Por exemplo:
INSERT INTO students (name) VALUES ('Ivan Ivanov');
INSERT INTO courses (title, student_id) VALUES ('Matematika', 1), ('Fizika', 1);
-- Apagando o aluno Ivanov
DELETE FROM students WHERE student_id = 1;
-- A tabela courses agora vai estar vazia, porque todos os cursos ligados ao Ivanov foram apagados
A gente vai ver esse assunto de novo e com mais detalhes na próxima aula.
Processo de validação de dados usando foreign keys
Quando você cria uma foreign key, o PostgreSQL vira tipo um porteiro chato, conferindo cada registro novo. Por exemplo:
- Se você tentar inserir um registro com um valor de foreign key que não existe, vai dar erro.
- Se você apagar um registro na tabela pai que tá ligado a outras tabelas (sem
ON DELETE CASCADE), isso vai dar problema de integridade dos dados.
Exemplo: tentando inserir dados errados
-- Tentando matricular um curso pra um aluno que não existe
INSERT INTO enrollments (student_id, course_id) VALUES (3, 1);
-- Erro: violação da restrição de foreign key
Erros comuns ao criar foreign keys
- Faltou criar índice na foreign key. O PostgreSQL cria índice automático pra primary key, mas não pra foreign key. Se você for usar muito a foreign key em
WHERE, vale criar o índice na mão. - Ordem errada na criação das tabelas. Não dá pra criar uma foreign key apontando pra uma tabela que ainda não existe.
- Esqueceu o modificador
ON DELETEouON UPDATE. Isso pode causar uns comportamentos estranhos quando você mexer nos dados.
Agora que você já sabe como criar foreign keys, ganhou uma ferramenta poderosa pra montar bancos de dados organizados e consistentes. Na próxima aula a gente vai detalhar mais como funcionam ON DELETE CASCADE e ON UPDATE RESTRICT pra controlar os dados relacionados.
GO TO FULL VERSION