CodeGym /Cursos /SQL SELF /Criando foreign keys ao criar tabelas

Criando foreign keys ao criar tabelas

SQL SELF
Nível 19, Lição 1
Disponível

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?

  1. 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.
  2. 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 students a gente criou a primary key PRIMARY KEY pra identificar cada aluno.
  • Na tabela courses a coluna student_id é a foreign key FOREIGN KEY, que aponta pra coluna student_id na tabela students.

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

  1. 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.
  2. Ordem errada na criação das tabelas. Não dá pra criar uma foreign key apontando pra uma tabela que ainda não existe.
  3. Esqueceu o modificador ON DELETE ou ON 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.

2
Tarefa
SQL SELF, nível 19, lição 1
Bloqueado
Criação de uma relação simples "um-para-muitos"
Criação de uma relação simples "um-para-muitos"
2
Tarefa
SQL SELF, nível 19, lição 1
Bloqueado
Criação de tabelas com ações `ON DELETE CASCADE`
Criação de tabelas com ações `ON DELETE CASCADE`
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION