Executando verificação de segurança...
5

Á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:

idnomesalariodepto
1Ana2500RH
2Carlos3800Vendas
3João4200TI

Consulta:

\sigma_{salario > 3000}(Funcionario)

Resultado:

idnomesalariodepto
2Carlos3800Vendas
3João4200TI

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:

nomedepto
AnaRH
CarlosVendas
JoãoTI

SQL:

SELECT nome, depto FROM Funcionario;

Exemplo 2 (Removendo Duplicatas):

Tabela com dados repetidos:

idnomecidade
1AnaSão Paulo
2CarlosRio
3AnaSão Paulo

Consulta:

\pi_{nome, cidade}(Clientes)

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

nomecidade
AnaSão Paulo
CarlosRio

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:

cortamanho
VermelhoP
VermelhoM
VermelhoG
AzulP
AzulM
AzulG

SQL:

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

Exemplo 2 (Com Dados Reais):

Tabela Alunos:

idnome
1Ana
2Pedro

Tabela Disciplinas:

coddisciplina
D1Matemática
D2História

Consulta:

Alunos \times Disciplinas

Resultado:

idnomecoddisciplina
1AnaD1Matemática
1AnaD2História
2PedroD1Matemática
2PedroD2História

SQL:

SELECT * FROM Alunos, Disciplinas;

Exercício Prático: Combinando Operadores

Dados:

  • Livros:

    idtitulopreco
    1Dom Casmurro50
    2Capitães de Areia45
    3Iracema30
  • Autores:

    idnome
    A1Machado de Assis
    A2Jorge 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:

idtituloprecoid_autornome
1Dom Casmurro50A1Machado de Assis
1Dom Casmurro50A2Jorge Amado
2Capitães de Areia45A1Machado de Assis
2Capitães de Areia45A2Jorge 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:

idnomecargo
1AnaAnalista
2CarlosGerente

Tabela Gerentes:

idnomecargo
2CarlosGerente
3JoãoGerente

Consulta:

Funcionarios \cup Gerentes

Resultado:

idnomecargo
1AnaAnalista
2CarlosGerente
3JoãoGerente

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:

idnomecargo
1AnaAnalista

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:

idnomecargo
2CarlosGerente

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

OperadorSímboloResultadoSQL Equivalente
UniãoTuplas em R ou SUNION
Diferença-Tuplas em R não em SEXCEPT/MINUS
InterseçãoTuplas em R e S simultaneamenteINTERSECT

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:

idnomesaldo
1Ana1000
2Carlos2500

Tabela Cartao:

idcliente_idlimite
C111500
C222000

Consulta:
Encontrar clientes com saldo maior ou igual ao limite do cartão

Cliente \bowtie_{saldo \geq limite} Cartao

Resultado:

idnomesaldoid_cartaocliente_idlimite
2Carlos2500C222000

SQL Correspondente:

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

Exemplo Prático 2:

Tabela Funcionario:

idnomesalariodepto_id
1Ana300010
2Carlos450020

Tabela Departamento:

idnome_deptoorcamento
10Vendas50000
20TI80000

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:

matriculanomecurso_id
1001Ana5
1002Carlos3

Tabela Curso:

curso_idnome_cursoduracao
3Engenharia5
5Medicina6

Consulta:

Aluno \bowtie Curso

Resultado:

matriculanomecurso_idnome_cursoduracao
1001Ana5Medicina6
1002Carlos3Engenharia5

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:

idnome_projetodepartamento
P1Sistema XTI
P2MarketingVendas

Tabela Funcionario:

idnomedepartamentocargo
1AnaTIAnalista
2CarlosVendasGerente

Consulta:

Projeto \bowtie Funcionario

Resultado:

id_projetonome_projetodepartamentoid_funcnomecargo
P1Sistema XTI1AnaAnalista
P2MarketingVendas2CarlosGerente

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

Comparação Entre Junções

CaracterísticaJunção ThetaJunção Natural
Condição de junçãoEspecificada explicitamente (θ)Automática (atributos com mesmo nome)
Atributos resultantesMantém todas as colunasElimina duplicatas de colunas de junção
FlexibilidadeQualquer condiçãoApenas igualdade em nomes
SQL equivalenteJOIN com ON/WHERENATURAL 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
2. 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:

codigonome_completosalario
.........

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_idproduto_id
1101
1102
1103
2101
2102
3101

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_idcurso_id
1001MAT101
1001FIS201
1002MAT101
1003MAT101
1003FIS201
1003QUIM301

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