Álgebra relacional

Produto cartesiano

Agora, veremos outra operação binária, chamada produto cartesiano (ou produto cruzado ou junção cruzada). O símbolo que a representa é ×\times.

Apesar de ser uma operação de conjunto binária, as relações sobre as quais ela é aplicada não precisam ser compatíveis. Isso significa que o número de colunas, bem como o tipo das colunas, não precisam ser os mesmos.

O produto cartesiano gera uma nova relação formada pela combinação de cada tupla da primeira relação com cada tupla da segunda.

A relação resultante Q tem uma tupla para cada combinação de tuplas — uma de R e uma de S. Logo, se R tem nRn_{R} tuplas (indicado como R=nR\lvert R\lvert = n_{R} ), e S tem nSn_{S} tuplas, então R × S terá nR×nSn_{R} \times n_{S} tuplas.

Vale destacar que, isoladamente, o produto cartesiano raramente tem utilidade prática. Ele se torna significativo quando combinado a uma operação de seleção, que impõe condições para relacionar atributos das relações envolvidas. Assim, primeiro ocorre a junção de atributos, e em seguida a filtragem das tuplas de interesse.

👨🏻‍💻 Da Álgebra Relacional para SQL

Em SQL, o PRODUTO CARTESIANO pode ser realizado usando a opção CROSS JOIN nas tabelas juntadas. Como alternativa, se houver duas tabelas na cláusula WHERE e não houver condição de junção correspondente na consulta, o resultado também será o PRODUTO CARTESIANO das duas tabelas.

1️⃣ Exemplo simples de produto cartesiano:

SELECT *
FROM funcionarios, setores;

2️⃣ Produto cartesiano seguido pela operação de seleção:

SELECT *
FROM funcionarios, setores
WHERE funcionarios.setor_id = setores.id

👨🏻‍💻 Código

CREATE DATABASE exemplo;
USE exemplo;

create table MONTADORA(
    id INT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(50) NOT NULL UNIQUE,
    pais VARCHAR(40) NOT NULL
);

create table MODELO(
    id INT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(50) NOT NULL UNIQUE,
    montadora_id INT,
    FOREIGN KEY (montadora_id) REFERENCES montadora(id)
);

INSERT INTO MONTADORA (nome,pais) VALUES ("Volkswagen","Alemanha");
INSERT INTO MONTADORA (nome,pais) VALUES ("Fiat","Italia");
INSERT INTO MONTADORA (nome,pais) VALUES ("Ford","Estados Unidos");

INSERT INTO MODELO (nome,montadora_id) VALUES ("Gol",1);
INSERT INTO MODELO (nome,montadora_id) VALUES ("Argo",2);
INSERT INTO MODELO (nome,montadora_id) VALUES ("Fiesta",3);
INSERT INTO MODELO (nome,montadora_id) VALUES ("Fusca",1);

Aplicando o produto cartesiano simples, temos o seguinte resultado:

SELECT * FROM MONTADORA, MODELO;
idnomepaisidnomemontadora_id
1FordEstados Unidos1Gol1
2FiatItalia1Gol1
3VolkswagenAlemanha1Gol1
1FordEstados Unidos2Argo2
2FiatItalia2Argo2
3VolkswagenAlemanha2Argo2
1FordEstados Unidos3Fiesta3
2FiatItalia3Fiesta3
3VolkswagenAlemanha3Fiesta3
1FordEstados Unidos4Fusca1
2FiatItalia4Fusca1
3VolkswagenAlemanha4Fusca1

Aplicando uma operação de seleção (σ\sigma) após o produto cartesiano:

SELECT * FROM MONTADORA,MODELO
WHERE MONTADORA.id = MODELO.montadora_id;
idnomepaisidnomemontadora_id
1VolkswagenAlemanha1Gol1
1VolkswagenAlemanha4Fusca1
2FiatItalia2Argo2
3FordEstados Unidos3Fiesta3

Para organizar melhor, podemos aplicar a operação de renomear (ρ)\rho):

SELECT m.id, m.nome, m.pais, c.id, c.nome
FROM MONTADORA AS M, MODELO AS C
WHERE m.id = c.montadora_id;
idnomepaisidnome
1VolkswagenAlemanha1Gol
1VolkswagenAlemanha4Fusca
2FiatItalia2Argo
3FordEstados Unidos3Fiesta