MC 536 - Álgebra Relacional x SQL : conexão prática |
SQL foi fortemente influenciada pelos trabalhos de Codd sobre Álgebra Relacional (AR)
e Cálculo Relacional de Tuplas (CRT). Embora elas sejam
equivalentes no que diz respeito ao poder de expressar consultas, SQL é
mais poderosa devido principalmente aos seus recursos de contagem, ordenação (cláusula order by )
e agrupamento (cláusula group by ). A AR e o CRT
podem ambas serem vistas como formas compactas de expressar consultas em SQL.
O domínio de uma delas pode ser de grande ajuda no raciocínio lógico por trás das soluções
de consultas complexas.
É o que faremos através de alguns exemplos da AR vistos em aula.
É importante ressaltar, no entanto, uma diferença conceitual importante entre
a AR e SQL: SQL não trata tabelas como conjuntos matemáticos, permitindo a
ocorrência de linhas duplicadas. Uma forma de evitar isto é sempre especificar
a chave primária ao criar uma tabela. Infelizmente isto não é suficiente, pois tabelas
intermediárias produzidas ao se executar um comando SQL podem conter linhas
duplicadas se certos cuidados não forem tomados: o exemplo mais simples desse efeito é
a operação de projeção (Π) que elimina duplicatas na AR mas a sua tradução natural para SQL
não o faz, sendo necessário colocar o qualificado distinct na cláusula select,
como veremos nos exemplos. A seguir, como operações da AR são traduzidas para SQL:
Exemplo: "Para cada funcionário apresente o seu número e os nomes dos seus dependentes"
AR: Π numf, nomed Dependentes SQL: select numf,nomed from Dependntes Obs: não há repetição porque por convenção, o par numf, nomed é Chave Primária de Dependentes"Dê uma lista dos funcionários que possuem dependentes"
Π numf Dependentes select numf from Dependentes problema: o funcionário 02 aparecerá duas vezes! É preciso incluir: select distinct numf from Dependentes
Π numf, nomed, par σ(par='filha')Dependentes select numf, nomed, par from Dependentes where par= 'filha'
Πp(D) ∩ Πf(D) select p from D intersect select f from D ou select distinct p from D where p in (select f from D)"Dê uma lista das pessoas que não têm filhos".
Πf(D) - Πp(D) select f from D except select p from D ou, select distinct f from D where f not in (select p frm D)
Exemplos: select ... from Funcionarios, Dependentes ou, select .... from D as D1, D as D2, D as D3 as é opcionalObserve também nesse exemplo os operadores de renomeação (alias na terminologia do SQL): as D1, as D2, etc. Usualmente o produto cartesiano será utilizado junto com uma seleção, conforme veremos.
Lembrando que a junção θ e a junção natural (mais precisamente junção de igualdade) são um subconjunto do produto cartesiano, obtido através de uma operação de seleção envolvendo comparação entre colunas, elas podem ser expressas através de uma expressão de comparação na cláusula where envolvendo as colunas escolhidas. Exemplos:
junção natural: "para cada funcionário que possui dependentes apresente o seu nome, os nomes e parentesco dos dependentes":
Πnomef, nomed, par Funcionarios |X| Dependentes ou, Πnomef, nomed, par σ(Funcionários.numf=Dependentes.numf)(Funcionarios x Dependentes) select nomef, nomed, par from Funcionarios, Dependentes where Funcionarios.numf = Dependentes.numfOutro exemplo: tabela de "pais e filhos", D(p,f):
ΠD1.p,D2.f σ(D1.f=D2.p)(D1 x D2) (Obs: aqui há uma renomeação implícita - qual é ela?) SQL: select D1.p, D2.f from D as D1, D as D2 where D1.f= D2.pExemplo de junção theta: "obtenha pares de pessoas sem repetição da tabela "Pais e Filhos", D( p, f), que são ou foram cônjuges, isto é, possuem um ou mais filhos em comum"
ρD1(p1,f1) D, ρD2(p2,f2) D Πp1,p2 (σ(p1 < p2 and f1=f2 (D1 x D2))
select distinct D1.p, D2.p from D as D1, D as D2 where D1.f = D2.f and D1.p < D2.p