CodeGym /Cursos /SQL SELF /Modelando relação ONE-TO-MANY entre tabelas...

Modelando relação ONE-TO-MANY entre tabelas

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

Agora chegou a hora de melhorar nossas skills e criar uma das relações mais comuns em bancos de dados relacionais — a relação ONE-TO-MANY.

Imagina uma empresa pequena. Um funcionário só pode trabalhar em um departamento, mas um departamento pode ter dezenas desses funcionários. Temos dois objetos do mundo real: funcionários e departamentos. A relação entre eles pode ser descrita como "um departamento pode ter muitos funcionários", ou formalmente "um para muitos" (ONE-TO-MANY).

Do mesmo jeito, relações ONE-TO-MANY aparecem em todo lugar:

  • um cliente pode fazer muitos pedidos;
  • um autor pode escrever vários livros;
  • um professor pode ensinar vários alunos.

No banco de dados relacional, a relação ONE-TO-MANY é feita usando uma chave estrangeira (FOREIGN KEY). Uma das colunas da tabela "muitos" (MANY) aponta para a chave primária da tabela "um" (ONE).

Como criar uma relação ONE-TO-MANY

Bora ver um exemplo clássico: a relação entre clientes e pedidos. Um cliente pode fazer vários pedidos, mas cada pedido está ligado só a um cliente. Vamos criar duas tabelas: customers (clientes) e orders (pedidos).

Tabela customers

Essa é nossa tabela "um". Ela vai guardar as infos dos clientes.

CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY, -- Identificador único do cliente
    name TEXT NOT NULL              -- Nome do cliente
);

Tabela orders

Essa é a tabela "muitos". Ela guarda os pedidos, onde cada pedido tem uma chave estrangeira customer_id que aponta para o customer_id da tabela customers.

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,           -- Identificador único do pedido
    order_date DATE NOT NULL,              -- Data do pedido
    customer_id INT REFERENCES customers(customer_id) -- Chave estrangeira
);

Aplicação prática

Inserindo dados

Agora vamos colocar alguns dados nas nossas tabelas pra testar a relação.

Vamos adicionar clientes na tabela customers:

INSERT INTO customers (name)
VALUES
    ('Ada Lovelace'),
    ('Grace Hopper'),
    ('Linus Torvalds');

Resultado:

customer_id name
1 Ada Lovelace
2 Grace Hopper
3 Linus Torvalds

Agora vamos adicionar pedidos na tabela orders:

INSERT INTO orders (order_date, customer_id)
VALUES
    ('2023-10-01', 1),  -- Pedido da Ada
    ('2023-10-02', 2),  -- Pedido da Grace
    ('2023-10-03', 1);  -- Mais um pedido da Ada

Tabela orders:

order_id order_date customer_id
1 2023-10-01 1
2 2023-10-02 2
3 2023-10-03 1

Repara: quando for adicionar um pedido, sempre coloca um customer_id que já existe. Se tentar colocar um ID que não existe, o banco vai dar erro. Isso protege a integridade dos dados.

Testando a relação

Agora vamos ver como as tabelas estão ligadas. Por exemplo, bora perguntar: quais pedidos a Ada Lovelace fez?

SELECT orders.order_id, orders.order_date, customers.name
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id
WHERE customers.name = 'Ada Lovelace';

Resultado:

order_id order_date name
1 2023-10-01 Ada Lovelace
3 2023-10-03 Ada Lovelace

Aqui a gente usou o comando JOIN pra juntar as duas tabelas usando a chave estrangeira. Prático, bonito — e sem dados duplicados!

Por que isso é importante

A relação ONE-TO-MANY é super comum e útil na vida real. Imagina uma loja online, com milhares de clientes e milhões de pedidos. Em vez de repetir as infos do cliente em cada pedido, a gente guarda os clientes únicos em uma tabela e os pedidos em outra. Isso diminui o tamanho dos dados e deixa o banco mais organizado.

Além disso, poder ligar os dados permite criar consultas poderosas pra análise. Por exemplo, dá pra perguntar: "Quantos pedidos cada cliente fez?" ou "Quais clientes fizeram pedidos no último mês?".

Dificuldades e pegadinhas

Olha onde a galera que tá começando geralmente tropeça:

Faltou a chave estrangeira. Se você esquecer de colocar a chave estrangeira na tabela "muitos", a relação vai ser só lógica (na sua cabeça), mas o banco não vai conseguir aplicar isso de verdade. Ou seja, você corre o risco de ter um banco "quebrado", com pedidos ligados a clientes que nem existem.

Tentar deletar um registro da tabela "um". Por exemplo, se você apagar um cliente da customers, os pedidos dele na orders vão ficar "órfãos". Pra evitar isso, dá pra usar ON DELETE CASCADE, assim quando o cliente for deletado, os pedidos dele também vão embora automaticamente.

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    order_date DATE NOT NULL,
    customer_id INT REFERENCES customers(customer_id) ON DELETE CASCADE
);

Agora, se você deletar um cliente:

DELETE FROM customers WHERE customer_id = 1;

Todos os pedidos dele também vão ser deletados. O banco fica limpo, igual café passado na hora.

Erros ao inserir dados. Se tentar inserir um pedido com um customer_id que não existe, vai receber um erro tipo:

ERROR:  insert or update on table "orders" violates foreign key constraint
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION