Álgebra relacional

Junção

Na aula anterior, conhecemos a operação binária produto cartesiano. Compreendemos também que tal operação é útil especialmente quando combinada com a operação unária de seleção (σ\sigma), uma vez que essa combinação de operações produz uma relação com tuplas coerentes.

Por conta de sua importância para a recuperação de informações em banco de dados relacionais, essa combinação de operações gera uma nova operação da álgebra relacional, chamada de junção, representada pelo símbolo \bowtie.

Há considerações importantes sobre a operação de junção:

  1. As tuplas cujos atributos de junção sejam nulos (NULL) ou cujo resultado da condição de junção seja falso (FALSE) não aparecem na relação resultante de uma junção.
  2. Assim, nota-se que tal operação não necessariamente preserva toda a informação das relações participantes, já que as tuplas que não satisfazem a condição não aparecem no resultado.

Equijunção

A equijunção é uma operação de junção em que a condição é expressa por um operador de igualdade.

Junção natural

Como a equijunção pressupõe que um par de atributos tenha valor igual (sendo um proveniente de cada relação), a relação resultante terá dois atributos contendo o mesmo valor. Essa repetição das colunas é desnecessária.

Uma nova operação, chamada de junção natural (\bowtie) é criada para representar, na álgebra relacional, a remoção do segundo atributo (desnecessário, por ser repetido) em uma condição de equijunção.

👨🏻‍💻 Exemplos de código

Relembrando o produto cartesiano

SELECT * FROM MONTADORA, MODELO;
+----+------------+----------------+----+--------+--------------+
| id | nome       | pais           | id | nome   | montadora_id |
+----+------------+----------------+----+--------+--------------+
|  3 | Ford       | Estados Unidos |  1 | Gol    |            1 |
|  2 | Fiat       | Italia         |  1 | Gol    |            1 |
|  1 | Volkswagen | Alemanha       |  1 | Gol    |            1 |
|  3 | Ford       | Estados Unidos |  2 | Argo   |            2 |
|  2 | Fiat       | Italia         |  2 | Argo   |            2 |
|  1 | Volkswagen | Alemanha       |  2 | Argo   |            2 |
|  3 | Ford       | Estados Unidos |  3 | Fiesta |            3 |
|  2 | Fiat       | Italia         |  3 | Fiesta |            3 |
|  1 | Volkswagen | Alemanha       |  3 | Fiesta |            3 |
|  3 | Ford       | Estados Unidos |  4 | Fusca  |            1 |
|  2 | Fiat       | Italia         |  4 | Fusca  |            1 |
|  1 | Volkswagen | Alemanha       |  4 | Fusca  |            1 |
+----+------------+----------------+----+--------+--------------+
12 rows in set (0.00 sec)

A operação de junção

SELECT * 
FROM MONTADORA
JOIN MODELO ON MONTADORA.ID = MODELO.MONTADORA_ID;
+----+------------+----------------+----+--------+--------------+
| id | nome       | pais           | id | nome   | montadora_id |
+----+------------+----------------+----+--------+--------------+
|  1 | Volkswagen | Alemanha       |  1 | Gol    |            1 |
|  1 | Volkswagen | Alemanha       |  4 | Fusca  |            1 |
|  2 | Fiat       | Italia         |  2 | Argo   |            2 |
|  3 | Ford       | Estados Unidos |  3 | Fiesta |            3 |
+----+------------+----------------+----+--------+--------------+
4 rows in set (0.00 sec)

Junção natural

Se aplicarmos a operação de junção natural em nossa base de dados, usando a seguinte expressão, o resultado será:

SELECT * FROM modelo NATURAL JOIN montadora;
Empty set (0.00 sec)

O resultado pode parecer estranho, mas é facilmente compreensível. Em nossas relações MONTADORA e MODELO, os atributos com nomes iguais chamam-se id e nome. Como a junção natural pressupõe a existência prévia de uma equijunção (junção com o operador de igualdade), ela buscará satisfazer a seguinte condição:

MONTADORA.id = MODELO.id, MONTADORA.nome = MODELO.nome

Observe que, por coincidência, a condição não é satisfeita em nenhuma situação. Por isso, o resultado é zero. Para contornar a situação, podemos renomear aplicar as operações de renomear.

SELECT * FROM modelo AS m
NATURAL JOIN (SELECT id AS montadora_id, pais FROM montadora) AS mont;
+--------------+----+--------+----------------+
| montadora_id | id | nome   | pais           |
+--------------+----+--------+----------------+
|            1 |  1 | Gol    | Alemanha       |
|            1 |  4 | Fusca  | Alemanha       |
|            2 |  2 | Argo   | Italia         |
|            3 |  3 | Fiesta | Estados Unidos |
+--------------+----+--------+----------------+
4 rows in set (0.00 sec)