Álgebra Relacional em Bancos de Dados

O que é Álgebra Relacional?

A álgebra relacional é uma linguagem formal que define um conjunto de operações para manipular relações (tabelas) em um banco de dados. Cada operação toma uma ou mais relações como entrada e produz uma nova relação como saída. Isso permite a construção de consultas complexas a partir de operações mais simples.

Importância da Álgebra Relacional

A álgebra relacional é importante porque:

  • Base Teórica: Fornece a base teórica para a linguagem SQL, que é amplamente utilizada para interagir com bancos de dados relacionais.
  • Otimização de Consultas: Ajuda na otimização de consultas, permitindo que os SGBDs escolham a melhor maneira de executar uma consulta.
  • Compreensão Profunda: Oferece uma compreensão mais profunda de como os dados são processados e manipulados nos bancos de dados.

1. Seleção (σ) - O Filtro de Linhas

(Equivalente ao WHERE do SQL)

Conceito Visual:

Imagine uma peneira que só deixa passar as linhas que atendem à condição.

Sintaxe Formal:

$$ \sigma_{\text{condição}}(R) $$

Como Funciona:

  • Recebe uma tabela de entrada (R)
  • Retorna apenas as linhas que satisfazem a condição
  • Não altera as colunas, só filtra linhas

Exemplo 1 (Básico):

Tabela Funcionário:

id nome salario depto
1 Ana 2500 RH
2 Carlos 3800 Vendas
3 João 4200 TI

Consulta:
$$ \sigma_{salario > 3000}(Funcionario) $$

Resultado:

id nome salario depto
2 Carlos 3800 Vendas
3 João 4200 TI

SQL Correspondente:

SELECT * FROM Funcionario WHERE salario > 3000;

Exemplo 2 (Condição Composta):

Consulta:
$$ \sigma_{depto='TI' \land salario < 4000}(Funcionario) $$

Resultado: (Nenhuma linha, pois João de TI ganha 4200)

SQL:

SELECT * FROM Funcionario 
WHERE depto = 'TI' AND salario < 4000;

2. Projeção (π) - O Seletor de Colunas

(Equivalente à lista de colunas no SELECT do SQL)

Conceito Visual:

Imagine um holofote que ilumina apenas certas colunas da tabela.

Sintaxe Formal:

$$ \pi_{\text{lista_de_colunas}}(R) $$

Como Funciona:

  • Recebe uma tabela de entrada (R)
  • Retorna todas as linhas, mas apenas com as colunas especificadas
  • Remove duplicatas se não houver chave primária

Exemplo 1 (Básico):

Consulta:
$$ \pi_{nome, depto}(Funcionario) $$

Resultado:

nome depto
Ana RH
Carlos Vendas
João TI

SQL:

SELECT nome, depto FROM Funcionario;

Exemplo 2 (Removendo Duplicatas):

Tabela com dados repetidos:

id nome cidade
1 Ana São Paulo
2 Carlos Rio
3 Ana São Paulo

Consulta:
$$ \pi_{nome, cidade}(Clientes) $$

Resultado: (Remove a duplicata Ana/São Paulo)

nome cidade
Ana São Paulo
Carlos Rio

SQL:

SELECT DISTINCT nome, cidade FROM Clientes;

3. Produto Cartesiano (×) - O Combinador Total

(Equivalente ao CROSS JOIN do SQL)

Conceito Visual:

Imagine duas listas sendo combinadas em todas as possibilidades possíveis.

Sintaxe Formal:

$$ R \times S $$

Como Funciona:

  • Combina cada linha da primeira tabela com todas as linhas da segunda
  • Número de linhas resultante = (linhas de R) × (linhas de S)
  • Cuidado! Pode gerar resultados muito grandes

Exemplo 1 (Básico):

Tabela Cores:

cor
Vermelho
Azul

Tabela Tamanhos:

tamanho
P
M
G

Consulta:
$$ Cores \times Tamanhos $$

Resultado:

cor tamanho
Vermelho P
Vermelho M
Vermelho G
Azul P
Azul M
Azul G

SQL:

SELECT * FROM Cores CROSS JOIN Tamanhos;
-- ou
SELECT * FROM Cores, Tamanhos;

Exemplo 2 (Com Dados Reais):

Tabela Alunos:

id nome
1 Ana
2 Pedro

Tabela Disciplinas:

cod disciplina
D1 Matemática
D2 História

Consulta:
$$ Alunos \times Disciplinas $$

Resultado:

id nome cod disciplina
1 Ana D1 Matemática
1 Ana D2 História
2 Pedro D1 Matemática
2 Pedro D2 História

SQL:

SELECT * FROM Alunos, Disciplinas;

Exercício Prático: Combinando Operadores

Dados:

  • Livros:

    id titulo preco
    1 Dom Casmurro 50
    2 Capitães de Areia 45
    3 Iracema 30
  • Autores:

    id nome
    A1 Machado de Assis
    A2 Jorge Amado

Consulta:
Queremos listar todos os livros com preço > 35 combinados com todos os autores:

Passo a passo:

  1. Filtrar livros:
    $$ \sigma_{preco > 35}(Livros) $$
  2. Combinar com autores:
    $$ \sigma_{preco > 35}(Livros) \times Autores $$

Resultado:

id titulo preco id_autor nome
1 Dom Casmurro 50 A1 Machado de Assis
1 Dom Casmurro 50 A2 Jorge Amado
2 Capitães de Areia 45 A1 Machado de Assis
2 Capitães de Areia 45 A2 Jorge Amado

SQL:

SELECT L.*, A.* 
FROM (SELECT * FROM Livros WHERE preco > 35) L
CROSS JOIN Autores A;

Operadores de Conjunto

1. União (∪) - Combinação de Resultados

Conceito:

Combina os resultados de duas relações, mantendo apenas uma ocorrência de cada tupla duplicada.

Sintaxe Formal:

$$ R \cup S $$

Requisitos:

  • As duas relações devem ter o mesmo número de colunas (union-compatíveis)
  • As colunas correspondentes devem ser do mesmo tipo

Exemplo Prático:

Tabela Funcionários:

id nome cargo
1 Ana Analista
2 Carlos Gerente

Tabela Gerentes:

id nome cargo
2 Carlos Gerente
3 João Gerente

Consulta: $$ Funcionarios \cup Gerentes $$

Resultado:

id nome cargo
1 Ana Analista
2 Carlos Gerente
3 João Gerente

SQL Correspondente:

SELECT * FROM Funcionarios
UNION
SELECT * FROM Gerentes;

2. Diferença (-) - Exclusão de Elementos

Conceito:

Retorna as tuplas presentes na primeira relação que não estão na segunda.

Sintaxe Formal:

$$ R - S $$

Exemplo Prático:

Consulta: $$ Funcionarios - Gerentes $$

Resultado:

id nome cargo
1 Ana Analista

SQL Correspondente:

SELECT * FROM Funcionarios
EXCEPT
SELECT * FROM Gerentes;
-- Ou alternativamente:
SELECT * FROM Funcionarios F
WHERE NOT EXISTS (SELECT 1 FROM Gerentes G WHERE G.id = F.id);

3. Interseção (∩) - Elementos Comuns

Conceito:

Retorna apenas as tuplas que estão presentes em ambas as relações.

Sintaxe Formal:

$$ R \cap S $$

Exemplo Prático:

Consulta: $$ Funcionarios \cap Gerentes $$

Resultado:

id nome cargo
2 Carlos Gerente

SQL Correspondente:

SELECT * FROM Funcionarios
INTERSECT
SELECT * FROM Gerentes;
-- Ou alternativamente:
SELECT F.* FROM Funcionarios F
INNER JOIN Gerentes G ON F.id = G.id;

Expressão Alternativa:

A interseção pode ser expressa usando diferença: $$ R \cap S = R - (R - S) $$

Comparação Entre os Operadores

Operador Símbolo Resultado SQL Equivalente
União Tuplas em R ou S UNION
Diferença - Tuplas em R não em S EXCEPT/MINUS
Interseção Tuplas em R e S simultaneamente INTERSECT

Importante!

  1. Compatibilidade de Esquema: Todas essas operações exigem que as relações tenham:

    • Mesmo número de colunas
    • Tipos de dados correspondentes compatíveis
  2. Eliminação de Duplicatas: Assim como em SQL, esses operadores eliminam tuplas idênticas automaticamente.

  3. Ordem Importa:

    • $R \cup S = S \cup R$ (comutativa)
    • $R - S \neq S - R$ (não comutativa)

Exercício Prático

Dadas as tabelas:

  • Clientes_Premium: (id, nome, data_cadastro)
  • Clientes_Ativos: (id, nome, ultima_compra)

Escreva as expressões para:

  1. Clientes que são premium mas não estão ativos
  2. Clientes que são premium e ativos simultaneamente
  3. Todos os clientes especiais (premium ou ativos)

Respostas:

  1. $Clientes_Premium - Clientes_Ativos$
  2. $Clientes_Premium \cap Clientes_Ativos$
  3. $Clientes_Premium \cup Clientes_Ativos$

Operadores de Junção

1. Junção Theta (⋈θ) - Junção com Condição Arbitrária

Conceito:

Combina tuplas de duas relações onde uma condição especificada (θ) é verdadeira. A condição pode ser qualquer comparação entre atributos.

Sintaxe Formal:

$$ R \bowtie_{\theta} S $$

Características:

  • θ pode ser qualquer operador de comparação: =, ≠, >, <, ≥, ≤
  • Mais genérico que a junção natural
  • Pode incluir múltiplas condições com AND/OR

Exemplo Prático 1:

Tabela Cliente:

id nome saldo
1 Ana 1000
2 Carlos 2500

Tabela Cartao:

id cliente_id limite
C1 1 1500
C2 2 2000

Consulta: Encontrar clientes com saldo maior ou igual ao limite do cartão $$ Cliente \bowtie_{saldo \geq limite} Cartao $$

Resultado:

id nome saldo id_cartao cliente_id limite
2 Carlos 2500 C2 2 2000

SQL Correspondente:

SELECT * FROM Cliente 
JOIN Cartao ON Cliente.id = Cartao.cliente_id 
WHERE Cliente.saldo >= Cartao.limite;

Exemplo Prático 2:

Tabela Funcionario:

id nome salario depto_id
1 Ana 3000 10
2 Carlos 4500 20

Tabela Departamento:

id nome_depto orcamento
10 Vendas 50000
20 TI 80000

Consulta: Funcionários com salário maior que 10% do orçamento do departamento $$ Funcionario \bowtie_{salario > 0.1*orcamento} Departamento $$

SQL Correspondente:

SELECT * FROM Funcionario F
JOIN Departamento D ON F.depto_id = D.id
WHERE F.salario > 0.1 * D.orcamento;

2. Junção Natural (⋈) - Junção Automática por Atributos Comuns

Conceito:

Combina automaticamente tuplas de duas relações com base em atributos com o mesmo nome, eliminando uma das colunas duplicadas.

Sintaxe Formal:

$$ R \bowtie S $$

Características:

  • Não precisa especificar a condição de junção
  • Atributos com mesmo nome são usados para a junção
  • Remove duplicatas dos atributos de junção

Exemplo Prático 1:

Tabela Aluno:

matricula nome curso_id
1001 Ana 5
1002 Carlos 3

Tabela Curso:

curso_id nome_curso duracao
3 Engenharia 5
5 Medicina 6

Consulta: $$ Aluno \bowtie Curso $$

Resultado:

matricula nome curso_id nome_curso duracao
1001 Ana 5 Medicina 6
1002 Carlos 3 Engenharia 5

SQL Correspondente:

SELECT A.matricula, A.nome, C.* 
FROM Aluno A NATURAL JOIN Curso C;
-- Ou explicitamente:
SELECT A.matricula, A.nome, C.curso_id, C.nome_curso, C.duracao
FROM Aluno A JOIN Curso C ON A.curso_id = C.curso_id;

Exemplo Prático 2:

Tabela Projeto:

id nome_projeto departamento
P1 Sistema X TI
P2 Marketing Vendas

Tabela Funcionario:

id nome departamento cargo
1 Ana TI Analista
2 Carlos Vendas Gerente

Consulta: $$ Projeto \bowtie Funcionario $$

Resultado:

id_projeto nome_projeto departamento id_func nome cargo
P1 Sistema X TI 1 Ana Analista
P2 Marketing Vendas 2 Carlos Gerente

Observação: A junção foi feita automaticamente pela coluna "departamento" comum a ambas as tabelas.

Comparação Entre Junções

Característica Junção Theta Junção Natural
Condição de junção Especificada explicitamente (θ) Automática (atributos com mesmo nome)
Atributos resultantes Mantém todas as colunas Elimina duplicatas de colunas de junção
Flexibilidade Qualquer condição Apenas igualdade em nomes
SQL equivalente JOIN com ON/WHERE NATURAL JOIN ou JOIN com colunas iguais

Exercício Prático

Dadas as tabelas:

  • Produto: (id, nome, preco, categoria_id)
  • Categoria: (id, nome_categoria, desconto_maximo)
  1. Escreva a junção natural entre el# Junções em Álgebra Relacional: Theta e Natural

Vamos explorar detalhadamente os dois tipos de junção na álgebra relacional, com exemplos práticos e comparações com SQL. as

  1. Escreva uma junção theta para produtos com preço menor que o desconto máximo da categoria

Respostas:

  1. $$Produto \bowtie Categoria$$
  2. $$Produto \bowtie_{preco < desconto_maximo \land Produto.categoria_id = Categoria.id} Categoria$$

SQL equivalente para 2:

SELECT * FROM Produto P
JOIN Categoria C ON P.categoria_id = C.id
WHERE P.preco < C.desconto_maximo;

Operadores Auxiliares

1. Renomeação (ρ) - Mudança de Nomes

Conceito Fundamental:

A operação de renomeação permite alterar:

  • O nome de uma relação (tabela)
  • Os nomes dos atributos (colunas)
  • Ambos simultaneamente

Sintaxe Formal:

  1. Renomear relação: $$ \rho_{nova_relacao}(R) $$

  2. Renomear atributos: $$ \rho_{a1 \to b1, a2 \to b2, ...}(R) $$

  3. Renomear ambos: $$ \rho_{nova_relacao(a1 \to b1, a2 \to b2, ...)}(R) $$

Casos de Uso Típicos:

  1. Resolver conflitos de nomes em operações de junção
  2. Criar relações temporárias com nomes significativos
  3. Preparar dados para operações subsequentes

Exemplo Prático 1 (Renomeação Simples):

Tabela Original:

Funcionario(id, nome, salario)

Consulta: $$ \rho_{Empregado}(Funcionario) $$

Resultado: A mesma tabela, mas agora chamada "Empregado"

SQL Correspondente:

CREATE VIEW Empregado AS SELECT * FROM Funcionario;
-- ou em consultas:
SELECT * FROM Funcionario AS Empregado

Exemplo Prático 2 (Renomeação de Atributos):

Consulta: $$ \rho_{id \to codigo, nome \to nome_completo}(Funcionario) $$

Resultado:

codigo nome_completo salario
... ... ...

2. Divisão (÷) - O Operador "Para Todos"

Conceito Fundamental:

Encontra tuplas em uma relação R que se relacionam com todas as tuplas em uma relação S.

Sintaxe Formal:

$$ R(A, B) \div S(B) $$

Onde:

  • R é uma relação com atributos A e B
  • S é uma relação com atributo B (subconjunto de R)
  • Resultado: valores de A que estão associados a todos valores de B em S

Exemplo Clássico:

Tabela Cliente_Produto (R):

cliente_id produto_id
1 101
1 102
1 103
2 101
2 102
3 101

Tabela Produtos_Especificos (S):

produto_id
101
102

Consulta: $$ Cliente_Produto(cliente_id, produto_id) \div Produtos_Especificos(produto_id) $$

Resultado:

cliente_id
1
2

Interpretação: Clientes 1 e 2 compraram ambos os produtos 101 e 102.

Implementação Alternativa:

A divisão pode ser expressa usando outros operadores: $$ R \div S = \pi_A(R) - \pi_A((\pi_A(R) \times S) - R) $$

Exemplo Prático 2 (Cursos Completo por Alunos):

Tabela Matricula (R):

aluno_id curso_id
1001 MAT101
1001 FIS201
1002 MAT101
1003 MAT101
1003 FIS201
1003 QUIM301

Tabela Curriculo_Base (S):

curso_id
MAT101
FIS201

Consulta: $$ Matricula \div Curriculo_Base $$

Resultado:

aluno_id
1001
1003

SQL Correspondente (versão 1):

SELECT DISTINCT aluno_id
FROM Matricula M1
WHERE NOT EXISTS (
    SELECT curso_id FROM Curriculo_Base
    EXCEPT
    SELECT curso_id FROM Matricula M2
    WHERE M2.aluno_id = M1.aluno_id
);

SQL Correspondente (versão 2):

SELECT aluno_id
FROM Matricula
WHERE curso_id IN (SELECT curso_id FROM Curriculo_Base)
GROUP BY aluno_id
HAVING COUNT(DISTINCT curso_id) = (SELECT COUNT(*) FROM Curriculo_Base);

Casos de Uso Comuns:

  1. Clientes que compraram todos os produtos de uma lista
  2. Alunos que cursaram todas as disciplinas obrigatórias
  3. Funcionários que trabalharam em todos os projetos de um departamento
  4. Fornecedores que fornecem todos os itens de um pedido

Referências