0% acharam este documento útil (0 voto)
1 visualizações58 páginas

banco_de_dados

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1/ 58

Capı́tulo 1

O Modelo Relacional

1.1 Relações Lógicas


Estamos no século XIX, ano de 1860 em Londres. Ainda era auge do império
colonial britânico, e Londres era possivelmente a cidade que mais crescia no
mundo. Tudo parecia que acontecia ali. Um professor da Universidade de
Londres, que estava a poucos anos de sua aposentadoria, estava escrevendo
uma obra de lógica, insatisfeito com a lógica de silogismo tradicional proposta
por Aristóteles na antiguidade. Os tempos de grande crescimento econômico
do Capital, estavam dando origem a um mundo muito mais complexo do que
havia antes e em todas as áreas novas teorias vinham se desenvolvendo trazendo
também visões de mundo que desafiavam as compreensões anteriores.
A filosofia tradicional estava em declı́nio. As correntes mais em voga era
o positivismo francês e o empirismo inglês. Ambas as filosofias defendiam sua
própria subordinação à ciência, que seria o triunfo diante dos estágios anteriores
de misticismo da humanidade. A fı́sica parecia que havia desvendado os prin-
cipais mistérios, exceto por alguns paradoxos e mistérios que pareciam menores
que precisavam ainda ser resolvidos. A quı́mica, mais atrás, estava prestes a
compreender os elementos e formar a primeira tabela periódica. Darwin ha-
via publicado um ano antes “A Origem das Espécies”, gerando uma polêmica
enorme ao desafiar as interpretações teológicas tradicionais sobre o surgimento
da vida e da humanidade. Karl Marx, um filósofo reconhecido mais entre ati-
vistas trabalhistas que entre outros acadêmicos, estava decidido a começar a
escrever sua análise econômica do capitalismo em “O Capital”.
E Augustus De Morgan, o professor da Universidade de Londres, era fruto
deste tempo. Como seus contemporâneos, parecia crer no domı́nio da ciência e
da razão para explicar o mundo, embora ele casasse isso com um lado espiritua-
lista. Junto com sua filha, tentou conduzir experimentações sobre fenômenos ti-
dos como paranormais. Os questionamentos à religião que vieram com o avanço
da ciência o fizeram rejeitar a interferência da igreja no estado e o levaram a
criar uma fé religiosa própria, dissidente em relação à igreja anglicana na qual

1
2 CAPÍTULO 1. O MODELO RELACIONAL

Figura 1.1: Augusto De Morgan: Nós sabemos que os matemáticos não se


importam com a lógica mais que os lógicos se importam com a matemática. Mas
os dois olhos da ciência exata são a matemática e a lógica: a seita matemática
remove os olhos da lógica e a seita lógica remove os olhos da matemática, cada
uma delas acreditando que com um olho vai enxergar melhor que com dois.

havia crescido. Mas De Morgan era antes de tudo um matemático e lógico já
reconhecido. E ele tinha ideias novas prestes a serem publicadas de como levar
o progresso para o campo da lógica.
Aristóteles dizia que se todo homem é mortal e Sócrates é um homem, po-
demos então deduzir que Sócrates é mortal. À partir de dois conhecimentos,
pudemos derivar um terceiro. Sabe-se que o mesmo raciocı́nio pode ser aplicado
em outros campos: Frida é uma gata e todo gato é um felino. Logo, Frida é
um felino. Ou, de maneira mais geral, A ← B e B ← C. Logo: A ← C. Não
importa o que é A, B ou C.
Mas Augustus De Morgan tinha uma insatisfação: segundo ele, nem toda
a lógica aristotélica era capaz de permitir que alguém percebesse que se uma
cabeça é parte de um cavalo e o cavalo é um animal, então a cabeça pertence
a um animal. Existia algo que faltava na lógica aristotélica, e isso era o que
ele chamava de relações. A relação “ser parte” é diferente da relação “ser
um”. Não é possı́vel conduzir muito além a lógica formal se a diferença entre
as relações não fosse compreendida. Do contrário, apenas seguindo silogismos,
alguém poderia dizer “Este cachorro é um poodle. Ele é meu cachorro. Logo,
ele é meu poodle.” e seguindo o mesmo raciocı́nio: “Este cachorro é um pai.
Ele é meu cachorro. Logo, ele é meu pai”.
Existem então relações que podemos chamar de “ser parte de”, “ser um”,
“pertencer a” e “ser o pai de”. Compreender como tais relações se comportam
é importante para saber que tipo de conclusão pode ou não pode ser obtida.
A relação “ser parte de”, pode ser inndicada por S: S(cabeça, cavalo) nos
diz que a cabeça é parte de um cavalo. E S(olho, cabeça) diz que o olho é parte
da cabeça. Esta é uma relação transitiva, pois se o olho é parte da cabeça e a
cabeça é parte do cavalo, então podemos deduzir que o olho é parte do cavalo.
1.1. RELAÇÕES LÓGICAS 3

É uma relação reflexiva, pois uma coisa pe sempre parte dela mesma. Então
S(x, x) é sempre verdade. E também é anti-simétrica, pois se x ̸= y, então se
existe a relação S(x, y), então não existe a relação S(y, x) (o fato da cabeça ser
parte de um cavalo e não ser um cavalo nos revela que um cavalo não é parte
de uma cabeça).
As relações “ser um” e “pertence a” tem exatamente as mesmas propriedades
transitiva, reflexiva e anti-simétrica. O que nos mostra que podemos agrupar as
relações em famı́lias que se comportam de maneira semelhante. Outro exemplo
de relação que compartilha as mesmas propriedades: quando um número divide
outro. Todo número divide a si mesmo, se ele divide x que divide y, então
tambem divide y. Mas se x divide y, então y não divide x se eles forem diferentes.
Toda vez que uma relação tem tal caracterı́stica de ser anti-simétrica, reflexiva
e transitiva, dizemos que ela foram uma ordem parcial sobre seus elementos.
Outro exemplo é a relação entre dois números x e y onde x ≤ y. Neste caso,
dizemos também que temos uma ordem total, pois para todo número, um
deles sempre será menor ou igual ao outro, sem que haja nenhum que escapa
desta ordenação.
Já a relação “ser pai de” é anti-simétrica (se Vader é pai de Luke, Luke nao
é pai de Vader), anti-reflexiva (uma pessoa nunca é o pai dela mesma) e anti-
transitiva (se assumirmos em nosso modelo famı́lias não incestuosas, este será o
caso; do contrário, perde-se esta propriedade). Pela diferença das propriedades
desta relação, ela realmente é bem diferente das demais. Em compensação,
a relação “ser descendente de” tem a transitividade. E como sempre que uma
pessoa é pai de outra, ela também é sua descendennte, então a relaçao de ser pai
é um refinamento da relação de ser descendente. Um exemplo de relação que
tem as mesmas propriedades de anti-simetria, anti-reflexividade e anti-transitiva
de “ser pai de” é quando “um número não divide outro”.
Uma relação não precisa ser sempre definida sobre dois elementos. Podem
existir uma quantidade arbitrária de elementos nela. Por exemplo, podemos re-
lacionar todas as pessoas que já viveram com o ano de seu nascimento e de sua
morte. Se chamarmos tal relação de H, temos que H(De Morgan, 1806, 1871),
H(Darwin, 1809, 1882) e H(Marx, 1818, 1883) são exemplos de tais relações. Na-
turalmente, torna-se mais difı́cil identificar propriedades tão gerais em relações
com mais elementos. A aridade de uma relação é o número de diferentes ele-
mentos que ela liga. Por exemplo, relações binárias tem aridade 2.
Note também que relações spodem ser definidas como conjuntos de tuplas
que as satisfazem. Sendo assim, podemos definir novas relações por meio da
união de duas outras, por meio da intersecção, da diferença e também de seu
complemento.
No fim, Augustus De Morgan obteve ainda mais reconhecimento por sua
contribuição para a lógica formal que complementou e enriqueceu o que se sabia
antes sobre a lógica de Aristóteles. Seis anos após a publicação de sua obra sobre
relações, ele iria se aposentar com ajuda de seus pupilos que lhe garantiriam uma
pensão. Seus últimos anos de vida seriam marcados pela tragédia da perda de
filhos e da deterioração de sua saúde mental, até morrer de causas que a medicina
do século XIX não era capaz de identificar corretamente.
4 CAPÍTULO 1. O MODELO RELACIONAL

Já a história da lógica formal e das relações continua. De Morgan pertenceu


a uma tradição de lógicos de sua época que buscavam estudar a lógica formal,
regida por regras matemáticas extremamente precisas, como uma maneira de
usá-la para adquirir uma compreensão mais profunda e completa da realidade.
Tal busca era desacreditada por alguns filósofos, mas todos eles à época do
século XIX, que era anunciada como uma era da razão e da ciência. Tal busca de
compreensão da realidade seguiu até o século XX, quando esta visão filosófica de
compreender o mundo por lógica formal perdeu força e teve que ser abandonada
após novas descobertas mostrarem que qualquer lógica formal suficientemente
complexa, a ponto de ser capaz de compreender aritmética, necessariamente não
era completa. O que significa que haviam sempre afirmações verdadeiras que
não poderiam ser alcançadas por meio das regras de inferência de tais lógicas. A
lógica formal então teve que recuar e se tornar uma ferramenta bastante útil para
a matemática e para compreender modelos de partes especı́ficas da realidade.
Sem mais ser vista como uma ferramenta à partir da qual somente por meio de
um raciocı́nio puro, premissas iniciais e de regras matemáticas precisas, toda a
compreensão da realidade estaria acessı́vel.

1.2 O Modelo Relacional de Banco de Dados


Cerca de 110 anos se passaram desde que De Morgan propôs as relações como
forma de aprimorar a lógica formal. A economia, o capital e a compreensão
cientı́fica se desenvolveram em um nı́vel tão alto que na época de De Morgan,
onde os pensadores já estavam deslumbrados com o desenvolvimento cientı́fico,
eles sequer sonhavam que ele avançaria tão longe.
A teoria de Darwin deixou de ser grande polêmica no meio cientı́fico, os
seus mecanismos já eram conhecidos, as teorias de Marx que antes eram re-
conhecidas só pelo trabalhismo agora haviam mostrado seu peso e contribuı́do
para a divisão do mundo em dois blocos econômicos, sendo um deles uma ten-
tativa de superação do capitalismo. No ano anterior, os primeiros astronautas
haviam caminhado na Lua, e tecnologias como satélites estavam começando a
serem usadas, enquanto computadores na forma de mainframes, eram ampla-
mente usados por governos, universidades e grandes corporações. Diferentes
linguagens de programação estavam florescendo nesta época, com pessoas pro-
gramando em Basic, FORTRAN (a mais popular desta época), LISP e Cobol,
sendo que a mais recente novidade era Pascal.
O grande crescimento e aumento da complexidade econômica e da própria
sociedade foram uma das forças motriz para o desenvolvimento dos computado-
res que automatizavam o processo de cálculo. Mas computadores agora também
precisavam armazenar uma grande quantidade de dados sobre o mundo. Com-
putadores de diversos governos já estavam armazenando dados sobre cada um
dos seus cidadãos. Companhias aéreas estava crescendo muito em paı́ses ricos,
e elas estavam precisando cada vez mais de um sistema unifocado para arma-
zenar informações sobre todos os vôos e cadastros. Até mesmo na América do
Sul, grandes petrolı́feras venezuelanas estavam se informatizando. Lembre-se
1.2. O MODELO RELACIONAL DE BANCO DE DADOS 5

Figura 1.2: Edgar Frank “Ted” Codd: A motivação mais importante para o
trabalho de pesquisa que resultou no modelo relacional era o objeticp de fornecer
uma divisória clara entre os aspectos lógicos e os aspectos fı́sicos do gerencia-
mento do banco de dados.

que para os padrões atuais, tais computadores tinham pouquı́ssima memória.


Todos eles que trabalhavam com uma grande quantidade de dados precisavam
fazer isso sem que todas as informações pudessem ser passadas para a memória
para acesso fácil.
A maior empresa de computadores da época era a IBM, onde trabalhava um
matemático inglês que havia se mudado para os Estados Unidos chamado Edgar
Codd. Ele havia acompanhado muitas das soluções da IBM para gerenciar gran-
des quantidades de dados, mas estava insatisfeito com elas. Nos últimos anos,
após concluir seu doutorado, Codd estudava como lidar com grandes quan-
tidades de dados e conhecia bem os sistemas que a IBM tinha. Eles eram
hierárquicos: com todos os dados armazenados em uma estrutura equivalente
ao sistema de arquivos de um computador, com diretórios e arquivos formando
uma organização interna em uma hierarquia. Um usuário que quisesse mani-
pular os dados, deveria ter um conhecimento de como eles eram armazenados
dentro da máquina, para poder navegar pelos diretórios corretos. E isso não
era só nos sistemas da IBM, mas também nos da concorrência. Um usuário
de banco de dados deveria ser um navegador: saber os caminhos pelos quais
deveria-se passar até chegar à onde o dado estava armazenado.
Codd não aprovava tal projeto. Ele acreditava que era necessário criar uma
separação entre a lógica interna de como o computador armazenava os dados,
e a lógica externa que deveria apresentar uma descrição baseada no mundo
real de como os objetos se relacionavam entre si. Usando assim, relações para
representar tais relacionamentos. Assim iria existir uma separação da definição
lógica dos dados e a implementação fı́sica do banco de dados. O que hoje é
chamado de princı́pio da independência de dados.
Codd sabia que as relações, como propostas por De Morgan, eram o meio
mais genérico de definir como os dados podiam se organizar entre si. Como um
exemplo, se quando apresentou suas propostas, Codd saı́sse para ver que filmes
6 CAPÍTULO 1. O MODELO RELACIONAL

Figura 1.3: Filmes de 1970: “Wanda” é sobre uma dona de casa de uma
região rural que, insatisfeita com a falta de perspectivas em sua vida após perder
o emprego, acaba se envolvendo com um assaltante de bancos. Ele ganharia o
prêmio de melhor filme estrangeiro no Festival de veneza. “Woodstock” é um
documentário sobre o festival de contracultura de mesmo nome que ocorreu um
ano antes.

estavam em cinema no cartaz, ele poderia observar uma relação entre o tı́tulo
dos filmes em cartaz, o diretor e um ator participante. E obteria assim a relação
F:
F (“Wanda”, “Barbara Loden”, “Barbara Loden”)
F (“Wanda”, “Barbara Loden”, “Michael Higgins”)
F (“Wanda”, “Barbara Loden”, “Frank Jourdano”)
F (“Wanda”, “Barbara Loden”, “Valerie Manches”)
F (“Woodstock”, “Michael Wadleigh”, “Janis Joplin”)
F (“Woodstock”, “Michael Wadleigh”, “Jimi Hendrix”)
F (“Woodstock”, “Michael Wadleigh”, “Joan Baez”)
F (“Woodstock”, “Michael Wadleigh”, “Joe Cocker”)
Note que todas as relações do mesmo tipo precisam ter sempre o mesmo
número de elementos e cada elemento de cada posição deve pertencer a um
mesmo tipo de conjunto. Se criarmos uma relação que contém todos os ato-
res de um filme, não podemos usar ela para comparar filmes que contém um
número diferente de atores, já que relações de números diferentes de elementos
são relações diferentes. Por causa disso, como é importante que todos os filmes
tenham um mesmo tipo de relação para poderem ser comparados, usamos o
modelo acima de relação ternária com nome do filme, diretor e ator, sendo que
uma nova relação é introduzida para cada ator.
Observando os cinemas da cidade de San jose onde estava, Codd poderia
observar uma relação C entre cada um dos cinemas e seu endereço e telefone:
C(“Cinelux Los Gatos Theatre”, “43 N Santa Cruz Ave Los Gatos”, 3999800)
C(“California Theatre”, “345 S 1st St San Jose”, 7924542)
C(“The Stanford Theatre”, “221 University Ave Palo Alto”, 3243700)
C(“Aquarius Theatre”, “430 Emerson St Palo Alto”, 3273241)
1.2. O MODELO RELACIONAL DE BANCO DE DADOS 7

C(“Studius Theatre”, “396 S. First Street”, 4699850)


E também pode-se obter uma relação S que é sobre as seções agendadas,
que contém o cinema, o nome do filme e o horário:
S(“Cinelux Los Gatos Theatre”, “Woodstock”, 20:30)
S(“California Theatre”, “Wanda”, 20:15)
S(“Aquarius Theatre”, “Woodstock”, 22:15)
S(“Studius Theatre”, “Wanda”, 20:45)
Não sabemos se Edgar Codd assistiu qualquer um destes filmes em um destes
cinemas. Mas o que ele imaginava era um novo tipo de banco de dados onde o
usuário pudesse pensar somente em termos de relações. À partir das relações
acima, novas informações que não estão armazenadas explicitamente poderiam
ser deduzidas, como por exemplo: tem algum filme onde o próprio diretor ou
diretora estão atuando? Qual o telefone do cinema em que está passando um
filme dirigido por Barbara Loden depois das 20:30?
Um usuário de banco de dados para Codd, deveria se preocupar somente
com este tipo de relação. Não em como ou onde o computador iria armazenar
internamente tais informações. Entretanto, para que sua ideia fôsse aceita, era
também preciso garantir que computadores realmente fôssem capazes de lidar
de maneira eficiente com as relações. E a própria IBM não apoiava as ideias de
Codd, pois isso significaria abandonar as soluções de bancos de dados que eles
já ofereciam.
Mas a ideia parecia viável. De maneira mais formal, na definição de Codd,
um banco de dados seria então uma tupla BD = (R, schema, dom), onde R
é um conjunto de relações (no caso do banco de dados de ciname acima R =
{F, C, S}). Já schema é uma função (ou mapeamento, ou relação) que associa
cada relação de R a uma tupla contendo um nome para cada elemento da relação.
Por exemplo:
schema(F ) = (“Tı́tulo”, “Diretor(a)”, “Ator”)
schema(C) = (“Cinema”, “Endereço”, “Telefone”)
schema(S) = (“Cinema”, “Tı́tulo”, “Horário”)
Note que é este esquema que nos mostra que os primeiros elementos da
relação C e S são iguais, bem como o primeiro elemento de F e o segundo de
S. Isso nos mostra que podemos deduzir novas relações além das que estão
explicitamente armazenadas de posse deste conhecimento.
Por fim, dom é um novo mapeamento (ou função, ou relação) que associa
cada atributo que aparece nas tuplas do contradomı́nio de schema a um con-
junto que representa o domı́nio dos elementos associados com tal atributo. Por
exemplo, dom(“Horário”) é o conjunto de todos os horários possı́veis, enquanto
dom(“Tı́tulo”) é o conjunto de todas as strings finitas que não são vazias. Mui-
tas vezes podemos omitir o domı́nio caso seja intuitivo deduzi-lo em nossos
exemplos.
8 CAPÍTULO 1. O MODELO RELACIONAL
Capı́tulo 2

Linguagens de Consulta e
Consultas Conjuntivas

Uma das primeiras tarefas feitas por Edgar Codd foi especificar uma linguagem
na qual consultas às relações de um banco de dados podiam ser feitas. Para
isso ele desenvolveu um novo tipo de álgebra, denominado álgebra relacional.
Depois, ele investigou também uma outra representação alternativa, o cálculo
relacional. Logo depois, outras pessoas começaram a desenvolver outros tipos
de linguagens mais práticas para seremm usadas em bancos de dados relacionais.
Iremos acompanhar esta história. Mas primeiro, vamos nos restringir a um
tipo muito especı́fico de consulta: as consultas conjuntivas. Elas são bastante
simples, mas máquinas conseguem responder elas bem rápido.

2.1 A Álgebra Relacional


Codd percebeu que como as relações são conjuntos de tuplas, poderiam ser
definidas operações sobre elas, como união, intersecção, etc. Mas nem todo
resultado destas operações necessariamente é uma relação. Por exemplo, a união
de uma relação binária com uma ternária não é uma relação. Por causa disso,
ele identificou que seria útil definir novos tipos de relação, os quais sempre iriam
gerar uma nova relação após receberem como entrada uma relação. Alguns dos
operadores que ele pensou:

• Seleção: Representada por σi=d (S), onde S é uma relação. O ı́ndice


i = d estabelece uma condição da consulta.
Por exemplo, se oı́ndice for Tı́tulo = “W oodstock ′′ significa que o segundo
elemento da relação S, que corresponde ao Tı́tulo, deve ser igual a “Woods-
tok”. Alternativamente, podemos escrever σTı́tulo=“W oodstock′′ (S) para ter
o mesmo efeito, desta vez invocando o nome do elemento do esquema asso-
ciado à S no banco de dados. Também podemos escrever σDiretor=Ator (F )
para representar que estamos interessados em relações com a propriedade

9
10CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

tal que seu segundo e terceiro elementos são os mesmos. Elementos do


domı́nio sempre irão aparecer entre aspas para diferenciá-los dos nomes
dos atributos.
O resultado da operação de uma seleção sobre uma relação S é uma nova
relação S ′ composta por todos os elementos de S para os quais a restrição
representada pelo seu ı́ndice é válida.
• Projeção: Este é o operador que permuta ou apaga as colunas de uma
relação. Ela é representada por πj1 ,...,jn (S), onde S é uma relação e
j1 , . . . , jn é uma sequência possivelmente vazia de nomes de atributos as-
sociados à relação. A operação irá retornar uma nova relação com aridade
igual à quantidade de elementos da sequência j1 , . . . , jn . Para cada ele-
mento em s ∈ S, existe no resultado s′ ∈ S ′ tal que s′ = (s[j1 ], . . . s[jn ]).

Com estas duas operações podemos resolver consultas bastante simples que
uma pessoa poderia fazer sobre o cinema de São Francisco em 1970:
Pergunta 1: Quem é o(a) diretor(a) de “Wanda”?
πDiretor(a) (σTı́tulo=“Wanda” (F ))
O operador σ primeiro descarta qualquer elemento da relação cujo tı́tulo do
filme não é “Wanda” e depois seleciona apenas a informação do diretor do filme,
produzindo uma nova relação de aridade 1 contendo apenas o nome do diretor
desejado.
Pergunta 2: Em quais cinemas posso assistir “Wanda”?
πCinema (σTı́tulo=“Wanda” (S))
Aqui fazemos algo parecido com a consulta anterior. Mas desta vez btemos
uma relação de aridade 2 e que contém diferentes cinemas que estão com o filme
escolhido em cartaz.
Pergunta 3: Qual o endereço e telefone do cinema “The Stanford Theatre”?
πEndereço, Telefone (σCinema=“The Stanford Theatre” (C))
Mas nem todas as consultas podem ser respondidas com os dois operadores
vistos. Um exemplo que requer novo operador é: “Cite o nome e endereço de
todos os cinemas que estão passando um filme de Michael Wadleigh”. Para isso
é necessário um operador novo:

• Junção Natural: Operação binária feita sobre duas relações R e S, de-


notada por R ▷◁ S. A nova relação resultante pode ser contruı́da obtendo
R ×S, com cada atributo de R e de S aparecendo na nova relação. Caso R
e S tenham atributos em comum, então somente uma cópia dele aparece
na relação R ▷◁ S, e qualquer elemento de R × S onde tais atributos tem
valores diferentes é descartada.

Como exemplo, podemos agora responder novas perguntas:


Pergunta 4: Cite o nome e endereço de todos os cinemas que estão passando
um filme de Michael Wadleigh.
πCinema, Endereço (πTı́tulo (σDiretor(a)=“Michael Wadleigh” (F )) ▷◁ S ▷◁ C)
Na consulta acima começamos obtendo todos os elementos de F onde o di-
retor é Michael Wadleigh e usamos uma projeção para obter somente os tı́tulos
2.1. A ÁLGEBRA RELACIONAL 11

dos filmes das relações encontradas. Usamos então a junção natural com S para
obter exatamente as relações que também tem os tı́tulos dos filmes encontrados,
e usamos outra junção, desta vez com C, para assim casar os elementos encon-
trados até agora com C, já que ambas as relações compartilham como atributo
o nome de cinemas. Com o resultado das junções, usamos uma última projeção
para remover todos os atributos que não estamos interessados, ficando só com
o nome do cinema e seu telefone.
Para enchergar melhor o quê está acontecendo, note que podemos representa
rerlações na forma de uma tabela ou matriz. E note que na fórmula abaixo,
começamos primeiro com a relação F :

 
“Wanda” “Barbara Loden” “Barbara Loden”
 “Wanda” “Barbara Loden” “Michael Higgins” 
 
 “Wanda” “Barbara Loden” “Frank Jourdano” 
 
 “Wanda” “Barbara Loden” “Valerie Manches”
F =
“Woodstock”

 “Michael Wadleigh” “Janis Joplin” 
“Woodstock” “Michael Wadleigh” “Jimi Hendrix” 
 
“Woodstock” “Michael Wadleigh” “Joan Baez” 
“Woodstock” “Michael Wadleigh” “Joe Cocker”

Depois de filtrarmos usando σ para obter somente os filmes do diretor Mi-


charel Wadleigh, obtemos a seguinte nova relação:

 
“Woodstock” “Michael Wadleigh” “Janis Joplin”
“Woodstock” “Michael Wadleigh” “Jimi Hendrix”
σDiretor(a)=“Michael Wadleigh” (F ) = 
“Woodstock”

“Michael Wadleigh” “Joan Baez” 
“Woodstock” “Michael Wadleigh” “Joe Cocker”

Fazendo a projeção com π de modo a ficarmos somente com o atributo Tı́tulo:


 
“Woodstock”

Temos também a relação S:


 
“Cinelux Los Gatos Theatre” “Woodstock” “20:30”
 “California Theatre” “Wanda” “20:15”
S= 
 “Aquarius Theatre” “Woodstock” “22:15”
“Studius Theatre” “Wanda” “20:45”

Ao fazer a junção natural (▷◁) das duas últimas relações representadas como
matrizes acima, identificamos que ambas as relações possuem um atributo Tı́tulo
em comum. Devemos então considerar apenas elementos do Tı́tulo que aparecem
nas duas relações e unir a coluna delas sem copiar redundantemente a coluna de
Tı́tulo. Essa operação é equivalente a filtrarmos da relação S somente os filmes
dirigidos por Michael Wadleight:
12CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

 
“Cinelux Los Gatos Theatre” “Woodstock” “20:30”
“Aquarius Theatre” “Woodstock” “22:15”
Observe agora a relação C:

 
“Cinelux Los Gatos Theatre” “43 N Santa Cruz Ave Los Gatos” “399 9800”

 “California Theatre” “345 S 1st St San Jose” “792 4542”
C=
 “The Stanford Theatre” “221 University Ave Palo Alto” “324 3700”
 “Aquarius Theatre” “430 Emerson St Palo Alto” “327 3241”
“Studius Theatre” “396 S. First Street” “469 9850”

Considere agora o resultado da junção natural das duas últimas tabelas.


Como mo atributo que elas tem em comum é o Cinema, juntamos as colunas de
cada linha que tem o valor de Cinema em comum:

 
“Cinelux Los Gatos Theatre” “Woodstock” “20:30” “43 N Santa Cruz Ave Los Gatos” “399 9800”
“Aquarius Theatre” “Woodstock” “22:15” “430 Emerson St Palo Alto” “327 3241”

E finalmente, como estamos interessados somente nos atributos Endereço e


Telefone, podemos usar uma projeção (π) para obtê-los:
 
“43 N Santa Cruz Ave Los Gatos” “399 9800”
“430 Emerson St Palo Alto” “327 3241”

É importante observar que a junção natural pode gerar uma nova relação com
uma quantidade de elementos (linhas na matriz) muito maior que a das relações
iniciais, apesar disso não ocorrer nos exemplos acima. Um exemplo, suponha
que estamos fazendo a junção de duas relações representadas pela matriz abaixo.
O esquema contendo os atributos da primeira relação é (A, B), e o esquema de
atributos da segunda é (B, C). Logo, a junção ocorre entre a segunda coluna
da primeira relação e a primeira coluna da segunda relação:
 
5 1 8
 5 1 16
 
  5 1 32
 
  
5 1 1 8 10 1 8 
 
10 1 ▷◁2,1 1 16 = 10 1 16
 
3 1 1 32 10 1 32
 
3 1 8
 
 3 1 16
3 1 32
Algumas vezes podemos querer realizar junções entre duas colunas que tem
atributos diferentes. Ou então, podemos querer simplesmente calcular o produto
cartesiano de duas relações que tem um atributo em comum. No primeiro caso,
podemos querer mudar o nome de um dos atributosde modo que as colunas que
2.2. O CÁLCULO RELACIONAL 13

queremos juntar tenham o mesmo nome de atributo. No segundo caso, podemos


querer mudar o nome de um atributo para que as duas relações não tenham mais
nenhum atributo em comum. Para isso, é útil definirmos uma última operação:

• Renomear: Operação unária feita sobre uma relação de modo que


mudemos o nome de um de seus atributos. Caso uma relação R tenha
um atributo chamado A e desejamos ter uma relação idêntica, mas com o
atributo A renomeado para B, denotamos tal operação por δA→B (S).

A álgebra relacional conforme mostrada aqui foi a tentativa de Edgar Codd


de fornecer uma linguagem de consulta a banco de dados relacionais.

2.2 O Cálculo Relacional


Embora a Álgebra Relacional fôsse uma nova notação interessante proposta por
Codd para se referir à consultas de informações sobre relações, já existia antes
na matemática uma notação formal para se referir à elementos que possuem
determinadas caracterı́sticas. Esta notação bastante poderosa era a lógica de
predicados.
Mas a lógica de predicados era expressiva demais. Em se tratando de con-
sultas a bancos de dados relacionais, somente um subconjunto dela é necessário.
Deste subconjunto obtemos o Cálculo Relacional.
Podemos expressar em Cálculo Relacional uma consulta conjuntiva usando
a seguinte forma:

{⟨e1 , . . . , em ⟩|∃x1 , . . . , xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}


Tal que todo e1 , . . . , em é uma variável que aparece em u1 , . . . , un e toda
variável de u1 , . . . , un é “declarada” ou em e1 , . . . , em ou em x1 , . . . xk .
Uma expressão deste tipo pode ser traduzida em português como: “Estamos
interessados em um conjunto de tuplas, cada um com m elementos, chamados
de e1 , . . . , em . Estes valores serão são o resultado da consulta que queremos. E
encontraremos eles assumindo que para quaisquer valores variáveis de x1 , . . . xk
(que serão usados nas nossas relações, assim como e1 , . . . , em ), uma lista de
relações R1 (u1 ), . . . Rn (un ) são todas, sem nenhuma exceção, válidas.
Como exemplo, vamos representar a consulta que nos dá a resposta da per-
gunta abaixo:
Pergunta 1: Quam é o(a) diretor(a) de “Wanda”?

{⟨e1 ⟩|∃x1 (F (“Wanda”, e1 , x1 ))}


O conjunto definido acima é equivalente a {⟨“Barbara Loden”⟩}, onde usa-
mos “⟨” e “⟩” para delimitar uma relação cujo nome não definimos.
Pergunta 5: Existe um filme dirigido por Michael Wadleigh em cartaz?

{⟨⟩|∃x1 , x2 , x3 , x4 (S(x1 , x2 , x3 ) ∧ F (x2 , “Michael Wadleigh”, x4 ))}


14CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Note que aqui não estamos interessados em qual é o filme, apenas se existe
ou não em cartaz um filme dirigido por Michael Wadleigh. Então expressamos
a nossa fórmula em cálculo relacional sem usar nenhum valor e1 . Se a propri-
edade de nossa consulta for válida, a consulta acima é equivalente ao conjunto
contendo uma relação vazia: {⟨⟩}. Se não for válida, nos retornará um conjunto
vazio: {} = ∅. Então podemos assim obter um resultado que será equivalente a
verdadeiro ou falso.
Note também que a variável livre x2 aparece em dois locais: no segundo
elemento da relação S e no primeiro da relação F . Sabemos que estas duas
posições representam um nome de filme. Com isso, a expressão S(x1 , x2 , x3 ) ∧
F (x2 , “Michael Wadleigh”, x4 ) só será verdadeira se existir um filme x2 dirigido
por Michael Wadleigh e se este filme estiver em cartaz (existir uma sessão para
ele na relação S que sabe quais filmes estão em cartaz em algum cinema). As
demais variáveis não tem tanta importância e existem apenas para preencher o
espaço de elementos existentes que não nos importa.
Pergunta 6: Liste os pares de pessoas tais que a primeira dirigiu a segunda
e a segunda tambémm já dirigiu a primeira.

{⟨e1 , e2 ⟩|∃x1 , x2 (F (x1 , e1 , e2 ) ∧ F (x2 , e2 , e1 ))}


Note que precisamos de duas variáveis x1 e x2 para representar os filmes
nos quais as relações indicadas são válidas. Se usássemos apenas x1 nos dois
casos, estarı́amos expressando uma consulta diferente: os pares de pessoas em
que ambas se dirigiram, uma à outra, exatamente no mesmo filme. Tendo as
duas variáveis, nós mantemos a possibilidade de que elas podem ter se mutu-
almente dirigido no mesmo filme, mas também abrimos a possibilidade de que
isso ocorreu em filmes diferentes.
Pergunta 7: Liste o nome de diretores que atuaram em um filme no qual
eles dirigiram.

{⟨e1 ⟩|∃x1 (F (x1 , e1 , e1 ))}


Nos dois primeiros anos após ter proposto o modelo relacional pela primeira
vez, Edgar Codd se dedicou a avaliar qual dos modelos seria mais poderoso: a
álgebra relacional ou o cálculo relacional.
Pode parecer talvez que o cálculo é mais expressivo, pois introduzimos alguns
truques novos quando o apresentamos. Por exemplo, na Pergunta 5, produzimos
uma consulta que retorna um conjunto vazio ou um conjunto com uma relação
vazia, dependendo do resultado ser verdadeiro ou falso. Mas isso também pode
ser obtido por meio da álgebra relacional: note que um operador de seleção (σ)
retorna um conjunto vazio se a relação não tem nenhum elemento onde a sua
igualdade é válida, e o operador de projeção (π) pode receber uma lista vazia de
colunas a serem selecionadas como ı́ndices, produzindo assim uma relação vazia
se receber uma relação não-vazia e um conjunto vazio se receber um conjunto
vazio. Desta forma, o mesmo efeito pode ser obtido via álgebra relacional.
A maior diferença que temos entre o cálculo relacional e a álgebra relacional,
é que tal como os definimos aqui, o primeiro atua diretamente sobre as relações,
2.2. O CÁLCULO RELACIONAL 15

ignorando informações especı́ficas de um banco de dados como o nome de atri-


butos e o domı́nio de cada elemento. Dizemos que ele tem uma perspective
sem nome, pois ele ignora o nome de cada atributo, se preocupando somente
com sua posição. Já a álgebra relacional vista adota uma perspectiva com
nome, usando de modo explı́cito os nomes de atributos para poder definir a
junção natural e a operação de renomear atributos. Mas esta é apenas uma
diferença de perspectiva, não dizendo respeito ao poder de representação dos
dois modelos.
Existem formulações alternativas da álgebra relacional para que ela se torne
uma perspectiva sem nome. Nelas, o operador ▷◁ é substituı́do pelo produto
cartesiano (×). Mas aqui preferimos apresentar ela em sua versão sob perspec-
tiva com nome apenas para deixar as coisas mais equilibradas. Fizemos com
que duas das linguagens de consulta apresentada neste capı́tulo sigam a pers-
pectiva sem nome (cálculo relacional e Datalog) e duas sigam uma perspectiva
com nome (álgebra relacional e SQL).

Teorema 1. O cálculo relacional sobre consultas conjuntivas (que segue o for-


mato descrito acima) é tão ou mais expressivo que a álgebra relacional sobre
consultas conjuntivas.

Demonstração. (Esboço) Para demonstrar isso, basta mostrar que qualquer


fórmula de álgebra de álgebra relacional seguindo as regras que definimos pode
ser representada em cálculo relacional.
Podemos definir uma fórmula de álgebra relacional por meio das seguintes
regras:

1. Se R é uma relação, então R também é uma fórmula de álgebra relacional.

2. Se F é uma fórmula de álgebra relacional, então σa=v (F ) também é uma


fórmula de álgebra relacional para a ∈ attr(F ) e v ∈ dom(a).

3. Se F é uma fórmula de álgebra relacional, então πa1 ,...,aj (F ) também é


uma fórmula de álgebra relacional, para a1 , . . . , aj ∈ attr(F ).

4. Se F é uma fórmula de álgebra relacional, então δa1 ←a2 (F ) também é uma


fórmula de álgebra relacional.

5. Se F1 e F2 são uma fórmula de álgebra relacional, F1 ▷◁ F2 também é uma


fórmula de álgebra relacional.

Para transformar qualquer fórmula de álgebra relacional em uma fórmula


de cálculo relacional, primiero interprete a fórmula algébrica, determinando a
ordem em que cada operação será feita, seguindo a precedência definida por
parênteses, ou seguindo os operadores da esquerda para a direita, quando não
há parênteses. Fazendo isso, uma árvore sintática será criada.
A árvore sintática deve ser percorrida, associando cada nodo dela a uma
fórmula de cálculo relacional, e também a um dicionário que associa cada
variável relevante a um atributo. Cada folha da árvore sintática sempre será
16CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

uma relação, e os elementos que não são folha correspondem sempre a operações
como σ, π, ▷◁ e δ. A fórmula correspondente à toda a expressão em cálculo re-
lacional é igual à fórmula da raı́z. Para obtê-la, seguimos as seguintes regras
recursivas:

1. Se estamos em uma folha, temos uma relação R de aridade n. Então, a


fórmula de cálculo relacional associado à ela é:

{⟨e1 , . . . , en ⟩| (R(e1 , . . . , en )}

Armazenamos também em um dicionário como cada valor se associa aos


atributos a1 , . . . , an da relação dentro do banco de dados: {(e1 , a1 ), . . . , (en , an )}.]

2. Se estamos em uma operação σa=v (F ), obtemos a fórmula de cálculo re-


lacional correspondente à F :

{⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}

Obtemos também o dicionário que associa cada variável a um nome de


atributo. Verificamos então qual o valor ea associado ao atributo a e
substituı́mos todas as ocorrências dele na fórmula pelo valor constante v:

{⟨e1 , . . . , v, . . . em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}

Removemos do nosso dicionário o elemento (ea , a) e colocamos no lugar


dele (v, a) para sabermos que o atributo correspondente ao valor constante
é a.

3. Se estamos em uma operação πa1 ,...,ai (F ), obtemos a fórmula de cálculo


relacional correspondente à F :

{⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}

Obtemos também o dicionário que associa cada variável a um nome de


atributo. Verificamos então quais os valores ea1 , . . . , eai associado aos
atributos a1 , . . . , ai e mantemos somente eles na parte esquerda da fórmula
antes de “|”, deixando-os na ordem indicada:

{⟨ea1 , . . . , eai ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}

Removemos do dicionário de atributos qualquer valor ej que não apareça


mais do lado esquerdo da fórmula, antes do “|”.

4. Se encontramos uma operação δa1 →a2 (F ), então copiamos aqui exata-


mente a mesma fórmula de cálculo relacional de F , mas atualizamos o
nosso dicionário de atributos, substituindo um valor (ei , a1 ) por (ei , a2 ).
2.2. O CÁLCULO RELACIONAL 17

5. Se encontramos uma operação de junção natural entre duas fórmulas


algébricas F1 e F2 , primeiro obtemos as fórmulas e dicionários de ambas,
e fazemos modificações necessárias para garantir que as variáveis da pri-
meira fórmula não apareçam na segunda, e vice-versa. Ao fim, ficaremos
com duas fórmulas de cálculo relacional:

{⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}

{⟨e′1 , . . . , e′m′ ⟩|∃x′1 , . . . x′k′ (R1′ (u′1 ) ∧ . . . ∧ Rn′ (u′n ))}

As duas fórmulas são então unidas gerando:

{⟨e1 ,...,em ,e′1 ,...e′m′ ⟩|∃x1 ,...xk ,x′1 ,...xk′ (R1 (u1 )∧...∧Rn (un )∧R1′ (u′1 )∧...∧R′ (u′n′ ))}

Em seguida, para cada atributo ei de F1 e ej de F2 que tenham exatamente


o mesmo atributo, renomeamos eles na fórmula acima para que tenham
exatamente o mesmo nome e, em seguida, removemos de ⟨e1 , . . . , e′m′ ⟩
qualquer variável repetida.
Se ao invés disso, tivermos uma constante C e uma variável ei com o
mesmo atributo, e cada um vindo de uma fórmula diferente, trocamos
todas as ocorrências de ei por C na fórmula e removemos o valor C re-
dundante de ⟨e1 , . . . , e′m′ ⟩.
Por fim, se tivermos duas constantes C1 de F1 e C2 de F2 , ambas com o
mesmo atributo, se C1 = C2 , apenas removemos uma delas de ⟨e1 , . . . , e′m′ ⟩.
Já se C1 ̸= C2 , então jogamos fora toda a fórmula e a substituı́mos por ∅,
pois temos uma restrição que não pode ser satisfeita.

Descrevendo o algoritmo acima, mostramos que qualquer fórmula de álgebra


relacional pode ser convertida em uma fórmula de cálculo relacional. Portanto,
como querı́amos demonstrar, o cálculo relacional é tão ou mais expressivo que
a álgebra relacional.
Teorema 2. A álgebra relacional sobre consultas conjuntivas é tão ou mais
expressiva que o cálculo relacional sobre consultas conjuntivas.
Demonstração. Seja a expressão de cálculo relacional abaixo.

{⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}


Sempre podemos convertê-la para uma expressão em álgebra relacional do
seguinte modo: primeiro estabeleceremos para cada relação R1 , . . . , Rn nomes
únicos de atributos, de modo que nenhuma delas tenha atributos em comum.
Em seguida, gere uma fórmula inicial que é igual à junção natural de todas as
relações: F0 = R1 ▷◁ . . . ▷◁ Rn . Isso é equivalente a obter o produto cartesiano
de todas as relações, já que elas não tem atributos em comum.
18CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Sobre cada fórmula Fn , obtenha uma nova fórmula Fn+1 da seguinte forma:
para cada par de variáveis em u1 , . . . , un que são iguais, produza Fn+1 =
σa=b (Fn ), onde a e b são os atributos gerados que são associados a cada uma
das variáveis escolhidas. Repita este procedimento adicionando mais seleções
até que tenha sido criada uma para cada par de variáveis idênticas existente.
Em seguida, para continuar obtendo novas fórmulas à partir da anterior,
para cada valor constante C que aparece em u1 , . . . , un , gere uma nova fórmula
Fn+1 = σa=C (Fn ), onde a é o atributo gerado que é associado à posição daquela
constante.
Por fim, quando não houverem mais constantes, deve-se pegar a fórmula Fn
obtida e gerar a Fn+1 = πa1 ,...,am Fn , onde a1 , . . . , am é um atributo associados
à uma ocorrência de cada variável e1 , . . . , em .
Seguindo o procedimento acima, podemos produzir uma fórmula de álgebra
relacional à partir de qualquer fórmula de cálculo relacional. POrtanto, isso
demonstra que a álgebra relacional é tão ou mais expressiva que o cálculo rela-
cional.

O corolário dos dois teoremas anteriores é que tanto o cálculo relacional


como a álgebra relacional sçao igualmente expressivos. Não há nada que um
deles possa expressar que o outro não possa. E esta foi a conclusão feita e
apresentada por Edgar Codd em 1972.

2.3 A Linguagem SQL


Edgar Codd havia cruzado os Estados Unidos, do extremo oeste de San Francisco
para o extremo leste em Nova Iorque. Foi uma viagem de pouco mais de cinco
horas de avião e estava lhe dando a oportunidade de conhecer pesquisadores
da IBM que trabalhavam no centro de pesquisa do outro ladodo paı́s. Aquela
também era uma chance para ele seguir propagandeando as suas ideias sobre
banco de dados em um simpósio sobre o assunto que estava ocorrendo.
Os pesquisadores de lá que estavam envolvidos com trabalhos com bancos de
dados, falavam sobre CODASYL, um dos modelos mais modernos existentes. Ao
contrário do modelo da IBM, o CODASYL não precisava ser hierárquico como
a estrutura de diretórios e arquivos de um computador. Os dados poderiam
ser armazenados em lógica arbitrária, e caberia ao usuáriodo banco de dados
navegar por caminhos que podiam ter qualquer topologia para armazenar e ler
os dados. Codd não estava impressionado. O que ele queria era que usuários de
bancos de dados não precisassem navegar.
Codd pediu a palavra e disse: “Claro, você pode expressar uma pergunta,
uma consulta ao banco de dados escrevendo um plano navegacional para recu-
perar a informação. Mas se você pensar sobre isso, o plano navegacional não
é a essência do quê você está tentando obter. Você está tentando obter a res-
posta para alguma pergunta, e você está expressando a pergunta na forma de
um plano de navegação. Não seria melhor se você apenas pudesse expressar a
pergunta e o sistema descobrisse por conta própria como navegar até ela? Se
2.3. A LINGUAGEM SQL 19

Figura 2.1: Donald D. Chamberlin: As ideias [de Edgar “Ted” Codd] não
tiveram apelo imediato aos usuários, acredito eu que era porque Ted apoiava
elas em simbolismo e terminologia matemática. Em sua linguagem de consulta
inicial, ele usava notação matemática, como quantificadores universais e exis-
tenciais, e ele usava muitas letras gregas. Coisas como estas dão a aparência do
assunto ser muito esotérico e difı́cil. Quando, na verdade, o que ele estava ten-
tando fazer era deixar as consultas mais simples, e não mais difı́ceis. Então eu
acho que o desenvolvimento de uma linguagem baseada em palavras em inglês,
que você pode digitar em um teclado comum, e a qual você pode ler e enten-
der intuitivamente, foi um grande avanço que tornou mais fácil para as pessoas
compreenderem a simplicidade que havia nas ideias de Ted. Isso não foi o que
tornou a ideia simples, foi o que fez com que ela se parecesse simples para os
outros.

você aumentar o nı́vel da linguagem que você usa para fazer perguntas para um
nı́vel mais alto e menos procedural, então as suas perguntas se tornam inde-
pendente do plano de navegação. Se as circunstâncias mudarem, o computador
pode mudar o plano. E você nem mesmo notaria a diferença. Você apenas
pensaria sobre a sua pergunta, e não como o computador faria para encontrar
a resposta.”
Uma das pessoas que estava assistindo a fala chamava-se Donald D. Cham-
berlin. Ele tambem era um jovem pesquisador da IBM que havia sido atraı́do
para a pesquisa cientı́fica inspirado pela corrida espacial e pelo lançamento do
satélite Sputnik, que ocorreu quando ele estava na oitava série. Anos depois
ele entraria na universidade para estudar Engenharia Elétrica (Ciência da Com-
putação era arriscado: ninguém sabia dizer se esse negócio de computadores
seria uma carreira duradoura) e faria lá um mestrado e doutorado na área de
engenharia elétrica depois da graduação. Um estágio o aproximou da IBM e
depois de terminar o doutorado, Donald Chamberlin tornou-se um pesquisador
na empresa. Poucos anos depois de entrar, com 28 anos de idade, era quando
ele assistiu a fala de Edgar Codd e foi convencido.
De fato, Chamberlin havia perdido todo o interesse em outros tipos de bancos
de dados. Havia percebido que com a abordagem relacional de Codd, consultas
20CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

que em outros modelos poderiam ser longos programas, poderiam se converter


em consultas relacionais de uma ou duas linhas. E assim que teve a chance,
conseguiu ser indicado para trabalhar no Sistema R, um sistema interno de
banco de dados experimental que a IBM estava fazendo para testar novas ideias
como as de Codd.
Chamberlin tinha ideias de como tornar realidade o seu banco de dados re-
lacional. Uma de suas principais motivações era tornar eles acessı́veis. Então
ele estabeleceu quatro objetivos ao projetar a nova linguagem de consulta rela-
cional:

1. Esqueça o termo “relação”. Melhor chamar isso de “tabelas”, porque todo


mundo sabe o que é uma tabela.

2. A linguagem deve ser semelhante ao inglês. Deve possuir termos em inglês


como “select” (selecionar).

3. A linguagem não deve possuir sı́mbolos especiais que não podem ser digi-
tados em um teclado simples.

4. Se possı́vel, um usuário sem treinamento algum, deve ser capaz de ler uma
consulta e entender o que ela faz.

O melhor amigo de Chamberlin, Raymond Francis Boyce, era um ano mais


novo, estava acabando naquele momento seu doutorado e também era um pes-
quisador na IBM. Ele juntou-se a Chamberlin no projeto de sua linguagem. E
durante os próximos anos ele iria trabalhar no projeto dela. Boyce e Chamberlin
inventaram um jogo para ajudá-los no objetivo: eles se alternavam pensando
em perguntas que poderiam ser feitas sobre os dados em um banco, e tentando
encontrar uma forma de expressar tais perguntas na linguagem que estavam
desenvolvendo. Além disso, a IBM destacou também uma psicóloga para acom-
panhar pessoas sem experiência de programação ao aprender a linguagem que
Boyce e Chamberlin estavam criando. Com isso, eles poderiam observar o que
causava mais dificuldade nas pessoas e como simplificar e facilitar mais o uso de
sua linguagem.
A linguagem levaria dois anos para ser desenvolvida. Inicialmente, ela era
chamada de SEQUEL. Mas este nome foi abandonado devido a um conflito
devido à tal nome já ser uma marca registrada. Por causa disso, depois o nome
mudaria para SQL, embora a pronúncia continuasse SEQUEL.
No espı́rito da linguagem SQL, as relações são interpretadas como tabelas.
Então podemos interpretar as relações F , C, S que vimos antes como as seguin-
tes tabelas:
2.3. A LINGUAGEM SQL 21

FILMES
TITULO DIRETOR ATOR
“Wanda” “Barbara Loden” “Barbara Loden”
“Wanda” “Barbara Loden” “Michael Higgins”
“Wanda” “Barbara Loden” “Frank Jourdano”
“Wanda” “Barbara Loden” “Valerie Manches”
“Woodstock” “Michael Wadleigh” “Janis Joplin”
“Woodstock” “Michael Wadleigh” “Jimi Hendrix”
“Woodstock” “Michael Wadleigh” “Joan Baez”
“Woodstock” “Michael Wadleigh” “Joe Cocker”
SESSOES
CINEMA TITULO HORARIO
“Cinelux Los Gatos Theatre” “Woodstock” “20:30”
“California Theatre” “Wanda” “20:15”
“Aquarius Theatre” “Woodstock” “22:15”
“Studius Theatre” “Wanda” “20:45”
CINEMAS
CINEMA ENDERECO TELEFONE
“Cinelux Los Gatos Theatre” “43 N Santa Cruz Ave Los Gatos” “399 9800”
“California Theatre” “345 S 1st St San Jose” “792 4542”
“The Stanford Theatre” “221 University Ave Palo Alto” “324 3700”
“Aquarius Theatre” “430 Emerson St Palo Alto” “327 3241”
“Studius Theatre” “396 S. First Street” “469 9850”
Uma vez que tenhamos os dados armazenados em sistema tabular, podemos
usar SQL para responder perguntas sobre ele.
Pergunta 1: Quem é o(a) diretor(a) de “Wanda”?

SELECT DISTINCT DIRETOR FROM FILMES WHERE TITULO="Wanda";

A linguagem SQL retorna desta consulta:


“Barbara Loden”
Em princı́pio, poderı́amos escrever apenas:

SELECT DIRETOR FROM FILMES WHERE TITULO=’Wanda’;

Mas isso nos retornaria:


“Barbara Loden”
“Barbara Loden”
“Barbara Loden”
“Barbara Loden”
E isso ilustra a diferença entre relações e as tabelas do SQL. Uma releção é
um conjunto, então nunca terá um elemento repetido. Fazer a consulta sem a pa-
lavra DISTINCT é mais eficiente, mas faz com que a consulta tenha redundâncias
se diferencie do que esperarı́amos das relações.
Pergunta 2: Em quais cinemas posso assistir “Wanda”?
22CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Responder esta pergunta segue a mesma lógica da anterior. Apenas muda-


mos o nome da tabela e das colunas:

SELECT DISTINCT CINEMA FROM SESSOES WHERE TITULO=’Wanda’;

A consulta acima retorna as duas linahs abaixo:


“California Theatre”
“Studius Theatre”
Pergunta 3: Qual o endereço e telefone do cinema “The Stanford Theatre”?
Responder esta pergunta requer obter informações de duas colunas diferen-
tes, ao invés de uma. Para isso, quando queremos retornar o resultado de mais
de uma coluna, separamos as colunas por vı́rgula na cláusula SELECT DISTINCT
<COLUNA(S)>:

SELECT DISTINCT ENDERECO, TELEFONE FROM CINEMAS WHERE CINEMA=’The Stanford Theatre’;

E a consulta acima retorna:


“221 University Ave Palo Alto” “324 3700”
Pergunta 4: Cite o nome e endereço de todos os cinemas que estão passando
um filme de Michael Wadleigh.
Agora devemos mostrar como combinar informações de duas tabelas dife-
rentes em SQL.

SELECT DISTINCT c.CINEMA, c.ENDERECO


FROM CINEMAS c, SESSOES s, FILMES f
WHERE f.DIRETOR=’Michael Wadleigh’ AND
f.TITULO=s.TITULO AND
s.CINEMA=c.CINEMA;

Na consulta SQL acima separamos melhor as três partes das consultas: a


cláusula de seleção SELECT DISTINCT, a cláusula que indica as tabelas FROM e a
cláusula com as condições WHERE.
Nós também mostramos que podemos nomear as tabelas, criando apelidos
temporários para elas. Fizemos isso na cláusulo FROM, criando o apelido “c” para
a tabela CINEMAS, “s” para a tabela SESSOES e “f” para a tabela FILMES. Usar
estes nomes nos permite identificar sem ambiguidade as colunas de diferentes
tabelas que possuem o mesmo nome.
Por exemplo, na cláusula SELECT DISTINCT, ao escrever c.CINEMA, estamos
dizendo que estamos interessados na coluna chamada CINEMA da tabela CINEMAS,
não da tabela SESSOES.
Finalmente, na cláusula WHERE, mostramos como escrever quando temos mais
de uma condição de consulta, onde todas elas devem ser verdadeiras. Primeiro
filtramos de “f” (FILMES) todas as linhas da tabela onde o diretor é Michael
Wadleigh. Depois, com base na coluna TITULO, de cada linha selecionada, en-
contramos em “s” (SESSOES) todas as linhas que também tem o mesmo valor
de TITULO. E para cada uma delas, achamos cada linha em CINEMAS que tem o
mesmo valor da coluna CINEMA.
2.3. A LINGUAGEM SQL 23

Podemos escrever cada uma das condições da cláusula WHERE em qualquer


ordem que desejarmos. Isso não vai influenciar no resultado obtido.
O resultado da consulta acima será:
“Cinelux Los Gatos Theatre” “43 N Santa Cruz Ave Los Gatos”
“Aquarius Theatre” “430 Emerson St Palo Alto”
Pergunta 5: Existe um filme dirigido por Michael Wadleigh em cartaz?
Agora temos a pergunta que não nos diz quais são os filmes, apenas pergunta
se existe ou não. Podemos então gerar a consulta abaixo que retorna uma única
linha e coluna se existir o filme, e não retorna nada se não existir:

SELECT DISTINCT true


FROM SESSOES s, FILMES f
WHERE f.DIRETOR=’Michael Wadleigh’ AND s.TITULO=f.TITULO;

O resultado desta consulta é:


1
Pergunta 6: Liste os pares de pessoas tais que a primeira dirigiu a segunda
e a segunda também já dirigiu a primeira.
Para responder esta pergunta, devemos comparar diferentes linhas de uma
mesma tabela, ao invés de linhas de tabelas diferentes ou de colunas que estão
em uma mesma linha. Isso torna esta consulta diferente das anteriores. Para
obter isso, podemos gerar duas cópias de uma mesma tabela e dar apelidos
diferentes para cada uma. Isso nos permite comparar diferentes linhas entre
elas:

SELECT DISTINCT a.DIRETOR, a.ATOR


FROM FILMES a, FILMES b
WHERE a.ATOR = b.DIRETOR AND b.ATOR = a.DIRETOR;

A consulta acima retorna:


“Barbara Loden” “Barbara Loden”
E também iria retornar a resposta correta se existissem pessoas diferentes
que atuaram juntas alternando o papel de ator e diretor em filmes diferentes.
Pergunta 7: Liste o nome de diretores que atuaram em um filme no qual
eles dirigiram.

SELECT DISTINCT DIRETOR FROM FILMES WHERE ATOR = DIRETOR;

A consulta acima agora leva em conta somente pessoas que foram atores e
diretores exatamente no mesmmo filme. Como basta comparar as colunas de
uma mesma linha, a consulta é bem mais simples e retorna:
“Barbara Loden”
Pergunta 8: Liste pares de atores que atuaram no mesmo filme.
Novamente temos que comparar diferentes linhas de uma mesma tabela. A
consulta abaixo responde à pergunta acima.

SELECT DISTINCT a.ATOR, b.ATOR FROM FILMES a, FILMES b WHERE a.TITULO = b.TITULO;
24CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Esta consulta nos retorna:


“Barbara Loden” “Barbara Loden”
“Barbara Loden” “Frank Jourdano”
“Barbara Loden” “Michael Higgins”
“Barbara Loden” “Valerie Manches”
“Michael Higgins” “Barbara Loden”
“Michael Higgins” “Frank Jourdano”
“Michael Higgins” “Michael Higgins”
“Michael Higgins” “Valerie Manches”
“Frank Jourdano” “Barbara Loden”
“Frank Jourdano” “Frank Jourdano”
“Frank Jourdano” “Michael Higgins”
“Frank Jourdano” “Valerie Manches”
“Valerie Manches” “Barbara Loden”
“Valerie Manches” “Frank Jourdano”
“Valerie Manches” “Michael Higgins”
“Valerie Manches” “Valerie Manches”
“Janis Joplin” “Janis Joplin”
“Janis Joplin” “Jimi Hendrix”
“Janis Joplin” “Joan Baez”
“Janis Joplin” “Joe Cocker”
“Jimi Hendrix” “Janis Joplin”
“Jimi Hendrix” “Jimi Hendrix”
“Jimi Hendrix” “Joan Baez”
“Jimi Hendrix” “Joe Cocker”
“Joan Baez” “Janis Joplin”
“Joan Baez” “Jimi Hendrix”
“Joan Baez” “Joan Baez”
“Joan Baez” “Joe Cocker”
“Joe Cocker” “Janis Joplin”
“Joe Cocker” “Jimi Hendrix”
“Joe Cocker” “Joan Baez”
“Joe Cocker” “Joe Cocker”
Perceba que se escrevêssemos a consulta incorreta abaixo:
SELECT DISTINCT ATOR, ATOR FROM FILMES WHERE TITULO = TITULO;
Então o resultado seria:
“Barbara Loden” “Barbara Loden”
“Michael Higgins” “Michael Higgins”
“Frank Jourdano” “Frank Jourdano”
“Valerie Manches” “Valerie Manches”
“Janis Joplin” “Janis Joplin”
“Jimi Hendrix” “Jimi Hendrix”
“Joan Baez” “Joan Baez”
“Joe Cocker” “Joe Cocker”
2.3. A LINGUAGEM SQL 25

Isso porque quando estamos fazendo consultas a uma mesma tabela, só po-
demos comparar os elementos de uma linha com os elementos da própria linha.
E se compararmos desta forma, TITULO = TITULO sempre vai ser verdadeiro em
todas as linhas (pois estamos comparando cada valor com ele mesmo). E o par
ATOR, ATOR é sempre o mesmo elemento repetido duas vezes.
Pergunta 9: Produza a resposta “O Poderoso Chefão” e “Francis Coppola”.
Na álgebra relacional e no cálculo relacional, isso é tão simples como gerar
uma nova relação ⟨“O Poderoso Chefão”, “Francis Coppola”⟩, ignorando qual-
quer outra relação pré-existente.
Em SQL, para gerar diretamente uma tabela de uma só linha com tais
valores, usamos uma expressão diferente:

VALUES(’O Poderoso Chef~


ao’, ’Francis Coppola’);

E isso ignora qualquer tabela existente, e simplesmente gera uma nova tabela
de uma só linha com o filme de 1972 e seu respectivo diretor:
“O Poderoso Chefão” “Francis Coppola”
Em suma, a linguagem SQL, tal como a definimos aqui, é formada por
consultas que tem uma das três formas diferentes:

VALUES(<valores>);
SELECT DISTINCT <colunas> FROM <tabelas>;
SELECT DISTINCT <colunas> FROM <tabelas> WHERE <condiç~
ao>;

A linguagem trata letras maiúsculas e minúsculas da mesma forma, então


tanto faz se escrevemos as letras em maiúsculas ou minúsculas. No primeiro caso
acima, apenas produzimos valores de resposta sem fazer consulta alguma. No
segundo caso acima, apenas selecionamos todas as colunas das tabelas indicadas,
sem testar nenhuma condição. O último caso é quando selecionamos as colunas
e linhas condicionalmente.
A parte em que especificamos colunas tem a forma de uma lista de colunas
separada por vı́rgulas, seguindo as regras de nomenclatura que vimos. As tabelas
que consultamos também são separadas por vı́rgulas quando há mais de uma,
podendo também especificar um apelido temporário para elas como mostramos.
Já as condições após o WHERE tem uma das duas forma abaixo:

<condiç~
ao> := <coluna>=<coluna ou literal>
<condiç~
ao> := <coluna>=<coluna ou literal> AND <condiç~
ao n~
ao vazia>

Basicamente podemos especificar como condição fórmulas de igualdade con-


juntivas, isto é, fórmulas em que todas as condições precisam ser satisfeitas. (Na
verdade, SQL permite outros tipos de fórmula, mas neste capı́tulo estamos nos
limitando a este formato.)

Teorema 3. A linguagem SQL é tão ou mais expressiva que a álgebra ou o


cálculo relacional.
26CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Demonstração. (Esboço). Isso pode ser demonstrado mostrando como converter


qualquer expressão de álgebra relacional para código SQL. Para isso, vamos
usar o mesmo método recursivo construindo uma árvore sintática que usamos
para mostrar que o cálculo relacional era tão ou mais expressivo que a álgebra
relacional.
Após construir a árvore sintática, a recursão é definida por:

1. Se estamos em uma folha da árvore, temos alguma relação R de aridade


n, à qual são associados os atributos a1 , . . . , an . Assumimos que existe
também uma tabela SQL que também tem o nome R de n colunas nome-
adas usando os mesmos atributos a1 , . . . , an e tal que cada linha da tabela
corresponde a n elementos para os quais a relação R é verdadeira.
Associamos o seguinte código SQL à tal folha:

SELECT DISTINCT a1 , . . . an FROM R;

Este código produz uma tabela com toda a relação.

2. Assuma que temos uma operação σa=b (F ), onde F é uma fórmula de


álgebra relacional, para a qual conhecemos um código SQL correspon-
dente. Se o código SQL correspondente não tem uma cláusula WHERE, nós
adicionamos ao final dele, antes do ponto-e-vı́gula:

WHERE a = b

Se o código SQL já tinha uma cláusula WHERE antes, então nós adicionamos
ao final dele, antes do ponto-e-vı́rgula:

AND a = b

3. Se temos uma operação deprojeção πai ,...,aj (F ) para uma fórmula de


álgebra relacional F , cujo código SQL equivalente nós conhecemos. Neste
caso, basta modificar o código SQL, deixando ele igual, exceto pela cláusula
SELECT DISTINCT, onde listaremos no lugar do código existente a lista de
colunas ai , . . . , aj .

4. Se temos uma junção natural F1 ▷◁ F2 sobre duas fórmulas de álgebra re-


lacional para as quais conhecemos códigos SQL correspondentes, geramos
um novo código para a junção delas da seguinte forma:

(a) Todas as tabelas do código de F1 e do código de F2 deverão ser unidas


em uma nóva cláusula FROM. Colocamos apelido temporário em todas
as tabelas, garantindo que não haja colisão ou conflito no apelido de
nenhuma tabela. Os nomes das colunas devem ser atualizados de
acordo.
2.3. A LINGUAGEM SQL 27

(b) Todas as colunas da cláusula SELECT DISTINCT do código SQL de


F1 e de F2 devem ser unidas na nova cláusula SELECT DISTINCT
que estamos criando. Graças aos apelidos temporários que demos às
tabelas, nenhum conflito ocorrerá nesta parte devido à duas colunas
de mesmo nome.
(c) Todas as cláusulas de WHERE do código de F1 e de F2 devem ser
unidas no novo código que estamos formando. Novamente, termos
atualizado os apelidos previne potenciais conflitos.
(d) Em seguida, para cada par de colunas (ai , aj ) que está listado na
nossa cláusula SELECT DISTINCT e que tenha o mesmo nome de
atributo, devemos adicionar na cláusula WHERE uma nova condição
AND ai = aj . Em seguida, removemos aj da cláusula SELECT DISTINCT.
Repetimos isso até não haverem mais colunas de mesmo atributo lis-
tadas ali.

5. Para o caso de mudanças de nomes δai →aj (F ) para uma fórmula de álgebra
relacional F , repare que no SQL não há necessidade de termos tal recurso.
A álgebra relacional precisa dele porque a junção natural é dependente do
nome dos atributos para poder ou não efetuar a junção natural. Já o SQL
pode comparar e manipular duas colunas quaisquer em qualquer uma de
suas operações, sem se importar se elas tem ou não o mesmo nome de
atributo.
Contudo, para implementar corretamente a tradução de fórmula de álgebra
relacional para SQL, assim como quando mostramos como fazer a tradução
para o cálculo relacional, precisamos manter um dicionário. No caso da
tradução para SQL, inicialmente o dicionário começa associando cada atri-
buto a uma coluna de mesmo nome: {(a1 , a1 ), . . . , (an , an )}. Posterior-
mente, para cada vez que ocorrer uma mudança de nome, vamos alte-
rando tal dicionário em cada trecho da fórmula para que possamos efetuar
a tradução correta para SQL. Para todos os operadores anteriores, con-
sultamos sempre o dicionário para saber qual é a coluna que realmente
corresponde ao atributo mencionado em cada operação.

As regras acima são capazes de traduzir qualquer fórmula de álgebra rela-


cional para SQL. Como o cálculo relacional também pode ser traduzido para
álgebra relacional, então isso significa que o SQL é também tão ou mais expres-
sivo que a álgebra e o cálculo relacional.

Teorema 4. A álgebra e cálculo relacional são tão ou mais expressivos que o


SQL.

Demonstração. Para demonstrar isso, mostraremos como converter qualquer


código SQL em uma expressão de cálculo relacional.
Um código como VALUES(a, b, c, ..., z) pode ser simplesmente conver-
tido para uma relação anônima com um só elemento: ⟨a, b, c, . . . , z⟩.
Considere o código abaixo:
28CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

SELECT DISTINCTa1 , . . . , an FROM b1 , . . . , bm WHERE t1 AND . . . AND tp ;

Devemos converter isso para algo na forma abaixo:

{⟨e1 , . . . , en ⟩∃x1 , . . . xv | (R1 (u1 ) ∧ . . . ∧ Rz (uz )))}

Para isso, começamos obtendo todas as tabelas SQL de b1 , . . . , bm levando


em conta apenas as tabelas distintas. Tabelas que são iguais, mas apenas tem
um apelido diferente são consideradas uma só tabela. Em seguida, associamos
cada coluna que aparece na cláusula SELECT DISTINCT a uma variável e1 , . . . , en .
Todas as outras colunas que não aparecem ali, serão associadas a outras variáveis
x1 , . . . , xv .
Para estabelecer os valores de R1 (u1 ), . . . , Rm (uz ), começamos associando
cada Ri (ui ) diferente a uma tabela distinta mencionada em b1 , . . . , bm (observe
que m ≥ z, pois a mesma tabela pode aparecer no código SQL mais de uma vez,
bastando ter apelidos diferentes). Então, cada ui corresponde à uma sequência
de variáveis associada a cada coluna da tabela representada por Ri .
Após criar uma versão inicial da fórmula de cálculo relacional, vamos atua-
lizá-la de acordo com os termos após a cláusula WHERE. Se não existir uma parte
WHERE no código SQL, o trabalho já estará terminado e temos a fórmula final.
Se houver um WHERE, para cada condição de igualdade a = b separada por AND
que existir na fórmula SQL:

1. Se a e b são colunas de tabela SQL, obtemos as duas variáveis xi e xj


associadas à elas. Substituimos então todas as ocorrências de xj por xi
dentro das fórmulas u1 , . . . , uz .

2. Se a é uma coluna SQL e b é um literal, um valor que a coluna precisa


ter, então encontramos a variável x associada à coluna a e substituimos
seu valor por b na fórmula, toda vez que ele aparecer em e1 , . . . , en e em
u1 , . . . , uz .

Após ter percorrido todas as condições no código SQL, verificamos na lista


de variáveis x1 , . . . , xk se alguma variável que tem ali não aparece mais em
nenhuma outra parte da fórmula. Se for o caso, nós a removemos de lá.
Com isso, podemos converter qualquer código SQL a uma fórmula de cálculo
relacional. Como ele também pode ser convertido para álgebra relacional, isso
significa que o cálculo e álgebra relacional são tão ou mais expressivos que o
código SQL.

O nosso corolário derivado dos teoremas é que em termos de capacidade de


expressão, cálculo relacional, álgebra relacional e SQL são linguagens equivalen-
tes.
2.4. DATALOG 29

2.4 Datalog
No mesmo ano em que Edgar Codd divulgou suas ideias sobre bancos de dados
relacionais, na França, Universidade de Aix-Marselha, um professor que havia
recém sido contratado estava alheio a tudo isso e não demonstrava interesse apr-
ticular em bancos de dados. Seus principais interesses no momento era conseguir
material para o novo departamento de computação que estava sendo criado, no
qual ele era um dos primeiros professores. Fora isso que o levou de volta à
França após ter passado os últimos anos estudando e terminando o doutorado
no Canadá.
Este professor se chamava Alain Colmerauer. Quando esteve no Canadá fa-
zendo sua pós-graduação, seu principal interesse não era banco de dados, mas
sim como desenvolver novas linguagens de programação e as técnicas necessárias
para reconhecer a sua sintaxe. Outro assunto que nos últimos anos vinha cha-
mando sua atenção era a inteligência artificial e como fazer com que um compu-
tador entendêsse mensagens escritas em linguagens naturais, como o português,
ou o francês. Esse interesse possivelmente foi influenciado por ele ter se casado
com uma linguista.
Assim que as coisas ficaram mais organizadas no nascente departamento de
computação da universidade, Alain Colmerauer voltou-se para um projeto que
ele tinha vontade de desenvolver. Uma inteligência artificial capaz de compre-
ender e se comunicar em francês. E o projeto começou a ser desenvolvido.
Sendo uma amostra das tentativas de desenvolvimento de inteligência ar-
tificial da época, em cerca de 2 anos depois, o projeto se desenvolveu em um
programa de computador com o qual era possı́vel ter a sequinte conversa (só
que em francês):

Usuário:
Gatos matam ratos.
Tom é um gato que n~ao gosta de ratos que comem queijo.
Jerry é um rato que come queijo.
Max n~ao é um rato.
O que Tom faz?
Computador:
Tom n~ao gosta de ratos que comem queijo.
Tom mata ratos.
Usuário:
Quem é um gato?
Computador:
Tom.
Usuário:
O que Jerry come?
Computador:
Queijo.
Usuário:
Quem n~ ao gosta de ratos que comem queijo?
30CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Computador:
Tom.
Usuário:
O que Tom come?
Computador:
Aquilo que gatos que n~ao gostam de ratos que comem queijo comem.
Usuário:
Todo psiquiatra é uma pessoa.
Toda pessoa que eles analizam está doente.
Jacques é um psiquiatra de Marseille.
Jacques é uma pessoa?
Computador:
Sim.
Usuário:
Onde está Jacques?
Computador:
Em Marseille.
Usuário:
Jacques está doente?
Computador:
Eu n~ao sei.

O programa era composto por dois módulos principais diferentes. O primeiro


era responsável por interpretar mensagens digitadas em francês, e era um dos
trabalhos de Alain. O outro módulo era responsável pela parte de realizar
deduções lógicas e foi em boa parte escrito por Philippe Roussel.
O método pelo qual o programa de computador poderia compreender que
Tom não gostava de Jerry era por meio de relações. O programa poderia
criar à partir da conversa a relação M atar(Gatos, Ratos). Ele compreendia
que “Gatos” e “Ratos”, por estar no plural, era um conjunto. E poderı́amos
estabelecer uma relação de quando um elemento pertencia a um conjunto:
Ser(T om, Gatos), Ser(Jerry, Ratos).
O programa poderia deduzir novos conhecimentos e realizar inferências lógicas
básicas à partir de relações. À época em que Donald D. Chamberlin e Ray-
mond Francis Boyce estavam desenvolvendo SQL, o núcleo deste programa de
inteligência artificial iria acabar sendo desvinculado de seu programa inicial e
passaria a ser usado como um novo tipo de linguagem de programação, chamada
de Prolog. Dando origem a um novo tipo de programação lógica.
Levou pouco tempo até que diferentes pesquisadores começassem a perceber
que bancos de dados relacionais e linguagens lógicas construı́das como forma de
interpretar e deduzir novas informações sobre relações eram conceitos que po-
deriam se complementar. E um subconjunto da linguagem Prolog denominado
Datalog acabou se desenvolvendo como um novo tipo de linguagem para realizar
consultas em bancos de dados e derivar informações presentes neles.
Por ser um subconjunto da linguagem Prolog, todo código Datalog é também
um código Prolog, embora o contrário não necessariamente seja verdade.
2.4. DATALOG 31

Figura 2.2: Alain Colmerauer: Em uma linguagem do tipo de Prolog III,


um programa é uma definição do subconjunto do domı́nio de uma estrutura
escolhida. Membros deste subconjunto são chamados de elementos admissı́veis.
O conjunto de elementos admissı́veis é geralmente infinito e constitui—de certo
modo—um enorme banco de dados. A execução de um programa busca descobrir
certas partes deste grande banco de dados.

Os programas Datalog são um conjunto de regras que tem a seguinte forma:

<cabeçalho> :- <corpo> .

A regra significa: se o corpo for verdade, o cabeçalho (que sempre será uma
relação) também será verdade. O sı́mbolo “:-” é uma forma de representar
“←”. Cada regra pode ser vista como uma consulta que gera uma nova relação,
especificando o que ela significa combase em outras relações conhecidas. Em
Datalog, termos que começam com letras maiúsculas sempre são interpretados
como variáveis. Relações começam por letras minúsculas. Vamos assumir então
que para Datalog as relações que vimos sobre filmes será chamada de filme, a
relação sobre sessões será sessao e a relação sobre cinemas será cinema. Vamos
então gerar consultas que respondem perguntas sobre a nossa base de dados de
exemplo.
POr hora, estamos também assumindo que qualquer relação que apareça no
cabeçalho não pode aparecer no corpo. Então o que estamos definindo é uma
versão não recursiva do Datalog. Com esta versão é também possı́vel responder
todas as perguntas que vimos até agora.
Pergunta 1: Quem é o(a) diretor(a) de “Wanda”?

diretor(X) :- filme("Wanda", X, Y).

O programa acima é uma consulta. Ela gera uma nova relação chamada
diretor. A relação diretor(X) será verdade para toda variável X tal que
f("Wanda", X, Y) seja verdade (para qualquer Y). De fato, Y não é uma variável
muito relevante e por causa disso, podemos trocá-lo por “ ” para indicar que é
uma variável anônima que não é usada em nenhum outro lugar da consulta:
32CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

diretor(X) :- f("Wanda", X, _).

Programas Datalog se assemelham em certos pontos com as fórmulas em


cálculo relacional. Eles também ignoram informações como “atributos” ou
“nome da coluna” que aparece na álgebra relacional e no SQL. Mas a sua sin-
taxe é mais enxuta que a do cálculo relacional, pois ele não coloca explicitamente
quantificadores existenciais (∃) e ele tem meios de indicar quais sçao as variáveis
que realmente importam para nossa consulta.
Pergunta 2: Em quais cinemas posso assistir “Wanda”?

nome_cinema(X) :- sessao(X, "Wanda", _).

Agora este código gera uma relação chamada nome cinema que será verdade
para dois valores X diferentes extraı́dos de nossa base de dados (“Califormia
Theatre” e “Studius Theatre”).
Pergunta 3: Qual o endereço e telefone do cinema “The Stanford Theatre”?
Aqui Datalog cria uma nova relação binária como resposta à consulta:

endereco_fone(X, Y) :- cinema("The Stanford Theatre", X, Y).

Pergunta 4: Cite o nome e endereço de todos os cinemas que estão passando


um filme de Michael Wadleigh.
Note que as variáveis não precisam ser apenas uma letra. A única restrição é
que elas devem começar com letra maiúscula. Mas em consultas mais complexas,
é importante dar nomes mais explicativos para elas.
O cabeçalho de uma regra Datalog não precisa ser apenas uma relação.
Podem haver mais de uma, separadas por uma vı́rgula que deve ser interpretada
como representando “∧”. Qunado isso ocorre, o cabeçalho será verdade quando
todos os termos do corpo forem verdade.

nome_endereco(Nome, Endereco) :- filme(Titulo, "Michael Wadleigh", _) ,


cinema(Cinema, Endereco, _) ,
sessao(Cinema, Titulo, _) .

Na consulta acima, definimos uma nova relação com o nome e endereço


que será verdade quando as três relações do corpo forem verdade. Note que há
conexão entre cada relação do corpo, pois elas compartilham as mesmas variáveis
em vários de seus termos. Isso nos mostra quais termos de cada relação precisam
ser iguais (cinema e sess~ ao devem possuir seus primeiros termos com o mesmo
valor, por exemplo), de modo análogo ao cálculo relacional.
Pergunta 8: Liste pares de atores que atuaram no mesmo filme.

par_atores(Ator1, Ator2) :- filme(X, _, Ator1) ,


filme(X, _, Ator2) .

Pergunta 9: Produza a resposta “O Poderoso Chefão” e “Francis Coppola”.


Isso pode ser obtido simplesmente usando um valor que sempre é verdadeiro
como corpo e escolhendo o cabeçalho desejado:
2.5. CONSULTAS CONJUNTIVAS 33

resultado("O Poderoso Chef~


ao", "Francis Coppola") :- true .

Quando o corpo é sempre vazio, podemos abreviar a regra da seguinte forma:

resultado("O Poderoso Chef~


ao", "Francis Coppola").

Regras deste tipo são chamadas de “fatos”.


Assim como no cálculo relaional, contudo, é necessário acrescentar uma res-
trição adicional para que uma regra Datalog faça sentido: toda variável que
aparece nocabeçalho de uma regra Datalog precisa aparecer também no corpo.
Isso significa que não podemos criar fatos contendo variáveis, somente constan-
tes. Do contrário, poderı́amos criar um fato fato(X) que seria verdadeiro para
um número infinito de valores X sem qualquer restrição. Esta restrição assegura
que a regra Datalog é segura. Isto é, ela produz uma quantidade finita de
resultados.
Devido à semelhança entre Datalog e o cálculo relacional, não é difı́cil se con-
vencer de que ambas as linguagens, tais como a definimos aqui, são equivalentes.
Então o Datalog não recursivo do modo como apresentado aqui é equivalente
em termos de expressividade a todos os modelos que vimos antes.

2.5 Consultas Conjuntivas


Todas as linguagens apresentadas até agora são capazes de realizar um certo tipo
de consulta, que chamamos de “consultas conjuntivas”. Este tipo de consulta
tem propriedades interessantes.
Consultas conjuntivas são monotônicas. Isso significa que se uma tupla
(x1 , . . . , xn ) faz parte do resultado de uma consulta conjuntiva feita a um banco
de dados, então ela continuará fazendo parte do resultado, mesmo que mais
informações sejam adicionadas ao banco de dados.
Ou, de maneira mais formal, se I e J forem um conjunto de relações, tais
que toda relaççao de I esteja em J, e se q é uma função que mapeia um conjunto
de relações de um banco de dados até o resultado de uma consulta monotônica
feita sobre ela, então q(I) ⊆ q(J).
Esta é uma importante propriedade. Se um banco de dados representa
relações que codificam conhecimento sobre uma faceta do mundo, as informações
dadas por consultas conjuntivas são aquelas que são atemporais: se sabemos
que um determinado filme esteve em cartaz em determinado cinema, nada que
aconteça no futuro tornará esta informação falsa (note que o banco de dados que
definimos em nosso exemplo não fala nada sobre eles estarem em cartaz agora,
não há qualquer informação de data, apenas que eles estiveram em cartaz em
algum momento).
Em termos de otimização de bancos de dados, a propriedade da monotoni-
cidade nos diz que qualquer resultado deste tipo de busca pode ser armazenada
em cache, e não será invalidada, mesmo que o banco de dados cresça para ter
mais informações.
34CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Outra propriedade útil é que podemos ter a certeza de que consultas con-
juntivas sempre podem ser satisfeitas para algum banco de dados, e sempre
teremos uma resposta finita se o banco de dados for finito. Afinal, se a ex-
pressamos como {⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}, à partir da
própria linguagem de consulta do cálculo relacional podemos monstar um banco
de dados que conterá exatamente R1 (u1 ), . . . , Rn (un ) que gerará um resultado
⟨e1 , . . . , em ⟩ para a consulta. E como comparamos apenas dados internos ao
próprio banco de dados, não há como uma consulta sobre um banco finito re-
sultar em uma resposta infinita.
Isso não seria verdade se pudéssemos expressar uma consulta de maneira
mais geral como:
{⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un )) ∧ ei = y}
O último termo é uma igualdade arbitrária. Neste caso, se y for valor ar-
bitrários que não aparecem em qualquer relação e seu domı́nio for infinito, esta
consulta poderia gerar um número infinito de valores para ei . Já se o domı́nio
de y for disjunto do de ei , então esta consulta nunca seria aceita e nunca geraria
qualquer resultado.
Contudo, é possı́vel permitir tal notação permitindo igualdade se restringir-
mos que cada elemento e1 , . . . , em só apareça nas expressões de igualdade se ele
for igual a uma constante ou igual a um elemento de relação do banco de dados.
Isso evita o problema de resultados potencialmente infinitos. As consultas sem
solução não seriam então um problema tão grande, pois seria fácil verificar se te-
mos uma consulta de tal tipo, apenas conferindo todas as igualdades e checando
se elas conectam dois valores constantes diferentes.
Datalog pode ser enriquecido permitindo igualdades seguindo o mesmo mo-
delo:
resultado(A, B, C) :- s(A, 2) , B = 1 , C = 5.

Mas segundo a regra mencionada, não poderı́amos permitir:


resultado(A, B, C) :- s(A, 2) , B = C .
Pois isso geraria um resultado infinito.
Note que permitir igualdades desta forma no cálculo relacional e em Data-
log não modifica em nada a expressividade da linguagem, pois exatamente as
mesmas consultas poderiam ser expressas sem a igualdade. E tal conceito não
se aplica de forma natural às consultas de álgebra relacional.
Já no caso do SQL, ele proibe igualdades envolvendo coisas que não sejam
constantes ou atributos de tabelas já existentes. Nunca podemos criar qualquer
tipo de igualdade envolvendo uma coluna da tabela de resposta. Esta é uma
restrição mais rigorosa do que a que mencionamos, pois não é possı́vel escrever:
SELECT DISTINCT DIRETOR, X FROM FILMES WHERE TITULO="Wanda" AND X = 1;
Se X não é uma coluna já existente, não pode ser usada. Ao invés disso,
para obter uma tabela em que temos sempre a segunda coluna igual a 1, escre-
verı́amos:
2.5. CONSULTAS CONJUNTIVAS 35

SELECT DISTINCT DIRETOR, 1 FROM FILMES WHERE TITULO="Wanda";

Outra propriedade relevante para as consultas conjuntivas é que elas são


fechadas em relação à composição: a composição de duas consultas conjuntivas
também é uma consulta conjuntiva.
Para compreender o que é uma composição de consultas, vamos mostrar
como podemos usá-las para responder à pergunta: “que filmes onde atua Ma-
rilyn Monroe estão em cartaz no Aquarius Theatre às 22:00”?
Note que esta consulta pode ser dividida duas. Primeiro podemos pergun-
tar “em que filmes atua Marilyn Monroe”? Depois podemos perguntar “que
filmes estão em cartaz no Aquarius Theatre às 22:00”? Depois de fazer as duas
perguntas, podemos juntar as respostas.
Em Datalog poderı́amos fazer isso:

filmes_monroe(Titulo) :- filme(Titulo, _, "Marilyn Monroe").


aquarius_dez_da_noite(Titulo) :- sessao("Aquarius Theatre", Titulo, "22:00").
resposta(Titulo) :- filmes_monroe(Titulo) ,
aquarius_dez_da_noite(Titulo) .

Um banco de dados armazena relações. O resultado de uma consulta é uma


nova relação. Portanto, cada resultado de uma consulta pode potencialmente
ser acrescentado ao banco de dados como uma nova relação, a qual pode ser alvo
de futuras consultas como qualquer outra. Se estamos usando uma relação que
é resultado de outra relação em uma consulta, estamos fazendo uma composição
de consultas. A composição de consultas conjuntivas também é uma consulta
conjuntiva.
De fato, composições não acrescentam nenhum poder expressivo à lingua-
gem. Mas ainda assim são um recurso útil para lidarmos com consultas muito
complexas que seriam muito longas de serem escritas. Consultas podem ser
armazenadas no banco de dados para serem usadas em composições, criando a
ilusão de que elas são tabelas reais, quando na verdade elas são deduzidas ao
invés de serem armazenadas diretamente. Estas tabelas virtuais são chamadas
de Exibições, ou Views. Em bancos de dados reais são particularmente úteis
para definir relações virtuais especı́ficas para diferentes tipos de usuários.
Enquanto Datalog permite criar Exibições temporárias restritas à uma execução
de um programa Datalog, em SQL a criação de Exibições é um processo per-
manente. Exibições criadas são sempre memorizadas. O código SQL que cria
as Exibições do exemplo acima são:

CREATE VIEW FILMES_MONROE AS


SELECT TITULO
FROM FILMES
WHERE ATOR = ’Marilyn Monroe’;
CREATE VIEW AQUARIUS_DEZ_DA_NOITE AS
SELECT TITULO
FROM SESSOES
WHERE CINEMA = ’Aquarius Theatre’ AND HORARIO = ’22:00’;
36CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Uma vez que estas duas Exibições tenham sido criadas, o seguinte código
SQL funcionaria:

SELECT a.TITULO
FROM FILMES_MONROE a, AQUARIUS_DEZ_DA_NOITE b
WHERE a.TITULO = b.TITULO;

2.6 Modelo de Computação para Bancos de Da-


dos
Tradicionalmente, em teoria da computação, uma das formas mais simples de
se modelar a computação em termos de compreender o que pode ou não ser
feito e quais os limites teóricos da computação é usando Máquinas de Turing.
Uma máquina de Turing tradicional é uma máquina que tem acesso a uma fita
infinita dividida em espaços discretos onde ela pode ler e escrever coisas usando
um alfabeto finito pré-determinado. A máquina sempre tem a sua cabeça de
leitura em uma posição da fita e em cada passo de execução ela pode ler, escrever
e mudar a posião da cabeça de leitura movendo-se para a esquerda ou direita.
O comportamento da máquina é descrito por um conjunto de estados e de uma
função de transição que na prática atuam como um programa de computador.
Inicialmente a fita de leitura e escrita da máquina de Turing está preenchida
com a entrada de um problema computacional, e demonstramos que o problema
é computável mostrando que existe uma máquina de Turing com um programa
interno capaz de resolvê-lo para qualquer entrada válida que estiver escrito na
fita.
Mas quando estamos lidando com a computação de uma consulta feita a um
banco de dados, lidamos com um tipo de problema bastante particular. O obje-
tivo de um sistema de banco de dados é gerenciar grandes quantidades de dados
compartilhados. E com grandes quantidades, isso significa que a quantidade é
grande demais para caber na memória.
Para modelar melhor o que significa computar sob tal restrição, um mo-
delo alternativo é de uma máquina de Turing com duas fitas. Uma das fitas
representa um banco de dados e tem tamanho n. Assumimos que n é um va-
lor limitado polinomialmente. Esta fita não pode ser escrita pela máquina de
Turing, ela só pode ser lida. A segunda fita da máquina de Turing pode tanto
ser lida ou escrita, é a chamada fita de trabalho. Entretanto, o tamanho da
fita de trabalho será sempre O(logn). Isso quer dizer que teremos sempre um
espaço de trabalho muito menor, representando nossa memória. É completa-
mente inviável copiar o conteúdo de entrada inteira para a fita onde a máquina
realiza o trabalho.
Máquinas de turing são capazes de aceitar ou rejeitar uma entrada. Elas são
modeladas para lidar com problemas computacionais na forma de problemas
de decisão. No caso da computação exigida para uma consulta a um banco
de dados, assumimos que a máquina de Turing que a representa aceita sua
2.6. MODELO DE COMPUTAÇÃO PARA BANCOS DE DADOS 37

Figura 2.3: Uma máquina de Turing com duas fitas. A fita de cima contém
um banco de dados e só pode ser lida. A fita de baixo, com um tamanho
consideravelmente menor, é onde a máquina pode realizar escrita.

entrada se o banco de dados possui algo que satisfaz a consulta, e ela rejeita
caso contrário.
A classe de problemas computacionais que pode ser resolvida sob tais condições
restritivas é chamada de L ou LOGSP ACE. Da teoria da computação, temos
que:

• L ⊆ P : Todo problema em L, sem exceção, pode ser resolvido em tempo


polinomial. Isso porque quando restringimos tanto assim o espaço de
memória para a computação, é possı́vel em tempo polinomial percorrer
todas as configurações possı́veis de uma máquina que reconhece uma lin-
guagem em LOGSP ACE.

• LOGSP ACE ⊊ P SP ACE: Existem problemas computacionais que pre-


cisam inerentemente de um espaço polinomial para serem resolvidos, e que
portanto, não são problemas em L. Por exemplo, se armazenarmos uma
fórmula em lógica de primeira ordem de tamanho n:

∃x1 ∀x2 . . . ∃xn−1 ∀xn (xi ∨ xj ∨ xk ) ∧ . . .

Não é possı́vel construir uma máquina de Turing que é capaz de responder


se esta fórmula pode ser satisfeita ou não usando somente um espaço
logarı́tmico. Portanto, este problema não está em L.

Contudo, não sabemos se L = P . Intuitivamente, ambos os conjuntos pa-


recem ser diferentes: parecem haver problemas computacionais que podem ser
resolvidos em tempo polinomial, mas que precisam de espaço polinomial para
serem resolvidos. Mas não há provas disso. Se ocorrer que L = P , este re-
sultado surpreendente nos mostraria que não existe nada que é possı́vel de ser
computado eficientemente em tempo polinomial que não possa ser computado
em espaço logarı́tmico. Na prática isso nos diria que tendo acesso à um banco
de dados, poderı́amos computar qualquer coisa razoável relacionada à ele, e que
o fato de que seu conteúdo não cabe na memória de nossa máquina é completa-
mente irrelevante. Isso também seria uma prova de que P ̸= P SP ACE.

Teorema 5. O probleama computacional de verificar se um banco de dados


satisfaz uma consulta conjuntiva de tamanho fixo pertence a L.
38CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Demonstração. Demonstrar isso envolve construir uma máquina de Turing que


consulta um banco de dados e identifica que ele satisfaz a consulta usando um
espaço logaritmico.
A nossa máquina de Turing representará uma consulta conjuntiva expressa
por {⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rp (up ))}. Ela funcionará iterando
sobre todo o banco de dados, percorrendo cada uma de suas posições várias
vezes. Ao fazer isso, ela irá copiar para a fita de trabalho, uma vez de cada,
cada elemento possı́vel de cada uma das relações R1 (u1 ), . . . , Rn (un ).
Para cada tupla de elementos R1 (u1 ), . . . , Rp (up ) copiados, a máquina de Tu-
ring irá comparar seus valores identificando as igualdades exigidas pela consulta
(note que todas as consultas conjuntivas envolvem somente testes de igualdade
e conjunções). Se ela achar uma tupla de elementos que satisfaz a consulta, a
máquina pára de executar e aceita sua entrada. Caso contrário, ela apaga os
valores copiados e continua procurando uma nova tupla.
Caso a máquina termine de testar todas as combinações possı́veis de elemen-
tos e nenhum deles tenha sido satisfeito, então a máquina pára, rejeitando sua
entrada.
Note que para iterar sobre todo o banco de dados, a máquina de turing
precisa armazenar o ı́ndice, ou um ponteiro, para a posição onde está o último
valor testado para R1 , R2 , até Rp . Se, por exemplo, o banco de dados tem
1000 células (n = 1000), então precisamos somente de 3 dı́gitos decimais para
representar qualquer posição nele. Já se o banco de dados tem tamanho n, só
precisamos de O(log n) células para armazenar o ponteiro para qualquer posição.
Como a consulta tem um tamanho contante, o número p de relações relevantes
para a consulta é uma constante. Portanto, só precisamos de O(log n) para
armazenar os ponteiros.
Além dos ponteiros, precisamos copiar para a fita de trabalho p diferentes
elementos para podermos comparar alguns de seus valores internos e identifi-
car se eles são iguais ou diferentes. A aridade máxima de cada relação que
procuramos é uma constante, como consequência da consulta ter um tamanho
constante. Portanto, a quantidade máxima de espaço que copiar os elementos
vai ocupar depende do tamanho máximo de cada elemento atômico armazenado
no banco de dados. Se for um tamanho limitado em O(log n) (um pressuposto
realista, cada elemento atômico em um banco de dados é muito menor que o
banco de dados em si), então este também será a quantidade de espaço que
ocuparemos copiando eles para a fita de trabalho.
Finalmente, a parte de computar a igualdade entre pares de valores na fita
de trabalho não requer nenhuma quantidade de espaço adicional. Portanto,
realizar consultas conjuntivas é um problema computacional em L.

Este tipo de complexidade em que assumimos que o tamanho da consulta é


constante e que o banco de dados tem tamanho n é chamada de complexidade
de dados.
Podemos também medir a complexidade combinada, quando assumimos
que tanto o banco de dados como a consulta tem tamanho n.
2.6. MODELO DE COMPUTAÇÃO PARA BANCOS DE DADOS 39

Figura 2.4: Exemplo de representação gráfica para o grafo G = (V, E) Onde


V = {a, b, c, d, e, f } e E = {{a, b}, {a, c}, {b, c}, {c, d}, {e, b}, {d, e}, {d, f }}.

Teorema 6. O problema computacional de avaliar uma consulta conjuntiva e


um banco de dados, ambos de tamanho n e retornar se o banco de dados satisfaz
a consulta é um problema NP completo.

Demonstração. Isso é provado mostrando que é possı́vel reduzir um problema


conhecido por ser NP-completo ao problema de avaliar consulta no banco de
dados. No caso, usaremos o problema de verificar se um clique de tamanho k
existe em um grafo.
Um grafo é uma tupla G = (V, E), onde V é um conjunto de vértices e E é
um conjunto de arestas, todas elas na forma {v1 , v2 }, com v1 , v2 ∈ V . Um clique
de tamanho k é um conjunto de k vértices em que todos eles estão conectados
entre si por meio de arestas.
Para reduzir este problema à uma consulta conjuntiva, crie um banco de
dados com a relação E(x, y) que é verdadeira se x e y forem vértices do grafo
e se eles estiverem conectados por uma aresta. Em seguida, crie uma consulta
conjuntiva com k(k−1)
2 termos diferentes da conjunção com k variáveis diferentes
sendo usadas, tal que cada par possı́vel destas variáveis seja representado por
um dos termos da conjunção.

Por exemplo, a tabela abaixo poderia representar o grafo da imagem acima,


enquanto a fórmula {⟨e1 , e2 , e3 ⟩| (V (e1 , e2 ) ∧ V (e2 , e3 ) ∧ V (e3 , e1 ))} pode encon-
trar todos os cliques de tamanho 3.

a b b a
a c c a
b c c b
c d d c
e b b e
d e e d
d f f d
40CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Isso demonstra a expressividade das linguagens de consulta como a definimos


até agora: apesar de não parecer, elas são capazes de resolver qualquer problema
computacional em NP.

2.7 União de Consultas Conjuntivas


Considere as seguintes perguntas:
Pergunta 10: Onde posso assistir o fime “Os Implacáveis” ou então “O
Ocaso de uma Estrela”?
Pergunta 11: Quais são os filmes em que “Woody Allen” aparece como
ator ou como diretor?
Pergunta 12: Que filmes em que “Woody Allen” é ator ou diretor estão
em cartaz em “The Monarch Theatre”?
Pergunta 13: Liste todos os filmes que foram dirigidos por Hitchcock ou
que estão em cartaz em “Roxy Theatre”.
Pergunta 14: Liste todos os atores e diretores do filme “O Poderoso
Chefão”.
Nenhuma das perguntas acima pode ser respondida pelas consultas seguindo
as regras que mostramos. Isso porque uma consulta conjuntiva é formado ape-
nas por conjunções: condições que precisam ser todas verdadeiras. Mas estas
perguntas pedem por uma disjunção: condições na qual somente uma delas
precisa ser verdadeira.
Embora tais consultas não possam ser feitas usando apenas consultas con-
juntivas, elas tornam-se possı́veis caso possamos realizar a união de consultas
conjuntivas. Por exemplo, quando na álgebra relacional podemos usar o ope-
rador ∪ para expressar uma relação que é a união de duas outras relações.
Contudo, tal operador precisa ser usado com cautela, pois não necessariamente
a união de duas relações também é uma relação. Por exemplo, se unirmos
relações que tem diferentes valores de aridade, nunca obtemos uma relação. Em
álgebra relacional também devemos nos certificar que o nome do atributo emtre
as relações sendo unidas também é compatı́vel.
Por exemplo, assim é como podemos responder às perguntas em álgebra
relacional:
Pergunta 10: Onde posso assistir o fime “Os Implacáveis” ou então “O
Ocaso de uma Estrela”?

πCinema (σTitulo=“Os Implacáveis” (S) ∪ σTitulo=“O Ocaso de uma Estrela” (S))

Pergunta 11: Quais são os filmes em que “Woody Allen” aparece como
ator ou como diretor?

πTitulo (σAtor=“Woody Allen” (F ) ∪ σDiretor=“Woody Allen” (F ))


Pergunta 12: Que filmes em que “Woody Allen” é ator ou diretor estão
em cartaz em “The Monarch Theatre”?
2.7. UNIÃO DE CONSULTAS CONJUNTIVAS 41

πCinema (σAtor=“Woody Allen” (F ) ∪ σDiretor=“Woody Allen” (F ) ▷◁ S)

Pergunta 13: Liste todos os filmes que foram dirigidos por Hitchcock ou
que estão em cartaz em “Roxy Theatre”.

πTitulo (σDiretor=“Hitchcock” (F )) ∪ πTitulo (σCinema=“Rocy Theatre” (S))

Pergunta 14: Liste todos os atores e diretores do filme “O Poderoso


Chefão”.

δAtor→Pessoa (πAtor (σTitulo=“O Poderoso Chefão” (F )))



δDiretor→Pessoa (πDiretor (σTitulo=“O Poderoso Chefão” (F )))

Na linguagem SQL, em um primeiro momento pode parecer que obter a


mesma capacidade de expressão requer apenas acrescentar condições “OR” às
cláusulas WHERE. E assim poderı́amos responder onde assistir “Os Implacáveis”
ou “O Ocaso de uma Estrela”:

SELECT DISTINCT CINEMA


FROM SESSOES
WHERE TITULO = ’Os Implacáveis’ OR
TITULO = ’O Ocaso de uma Estrela’;

Poderı́amos responder quais filmes Woody Allen foi ator ou diretor:

SELECT DISTINCT TITULO


FROM FILMES
WHERE DIRETOR = ’Woody Allen’ OR ATOR = ’Woody Allen’;

E quais deles estão em cartaz em determinado cinema:

SELECT DISTINCT s.TITULO


FROM FILMES f, SESSOES s
WHERE (f.DIRETOR = ’Woody Allen’ OR f.ATOR = ’Woody Allen’) AND
f.TITULO = s.TITULO AND s.CINEMA = "The Monarch Theatre";

Poderı́amos listar os filmes de Hitchcock junto com todos os que estivessem


em cartaz em um cinema:

SELECT DISTINCT f.TITULO


FROM FILMES f, SESSOES s
WHERE f.DIRETOR = ’Hitchcock’ OR (f.TITULO = s.TITULO AND
s.CINEMA=’Roxy Theatre’);
42CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS

Entretanto, isso não é expressivo o bastante para sermos capazes de listar


todos os atores e diretores de um determinado filme. Isso porque a linguagem
SQL não permite colocar um OR na cláusula SELECT DISTINCT. Sendo assim,
não terı́amos nenhuma forma de unir as duas diferentes colunas em uma só.
O OR não nos ajuda a alcançar a capacidade expressiva da união de consultas
conjuntivas. Para isso, é necessário ao invés disso introduzir a operação UNION
do SQL:
Pergunta 14: Liste todos os atores e diretores do filme “O Poderoso
Chefão”.
SELECT ATOR FROM FILME WHERE TITULO=’O Poderoso Chef~
ao’
UNION
SELECT DIRETOR FROM FILME WHERE TITULO=’O Poderoso Chef~ao’;
Uma peculiaridade da linguagem SQL é que a operação UNION sobre duas
tabelas efetivamente trata as tabelas como relações, isto é, como conjuntos de
tuplas que a satisfazem. Então após uma operação de UNION quaçquer elemento
repetido é descartado e por esta razão não precisamos usar SELECT DISTINCT
na consulta acima. Mas se tivéssemos colocado, não teria feito diferença.
Ao contrário do SQL, o cálculo relacional consegue representar consultas
para responder todas as perguntas acima apenas usando um operador “∨”. Por
exemplo, pode-se responder a pergunta 14:

{⟨n⟩|∃x1 , x2 (F (“O Poderoso Chefão”, x1 , n) ∨ F (“O Poderoso Chefão”, n, x2 ))}


Entretanto, inserir disjunções no cálculo relacional é algo bastante delicado.
Existem condições a mais que devem ser checadas para se certificar de que não foi
escrita uma consulta com infinitos resultados. Por exemplo, a seguinte consulta
em cálculo relacional vai produzir uma união de dois conjuntos infinitos caso a
relação R não seja vazia:

{⟨e1 , e2 , e3 ⟩| (R(e1 , e2 ) ∨ R(e2 , e3 ))}


Nós não consideramos a consulta acima como válida, justamente por causa
dela produzir um número infinito de respostas. Nem sempre é tão simples iden-
tificar quando uma fórmula em cálculo relacional produz um valor infinito, e isso
tem relação com a flexibilidade da linguagem: à medida que acrescentamos ele-
mentos à este cálculo, podemos acabar chegando ao cálculo de primeira ordem,
que é sabido ser Turing completo em sua capacidade de expressão. Uma forma
de evitar a ocorrência de consultas com infinitos resultados, seria exigir que
cada disjunção obrigatoriamente contenha entre suas variáveis todo e1 , . . . , en
que aparece no cabeçalho da expressão.
Por fim, temos o exemplo do Datalog, onde a união de consultas conjunti-
vas é expressa simplesmente escrevendo mais de uma regra que compartilha a
mesma relação do cabeçalho. A linguagem Datalog implicitamente faz a união
das consultas quando encontra cabeçalhos com uma relação de mesmo nome e
mesma aridade:
2.7. UNIÃO DE CONSULTAS CONJUNTIVAS 43

Pergunta 10: Onde posso assistir o fime “Os Implacáveis” ou então “O


Ocaso de uma Estrela”?

onde_assistir(NomeCinema) :- sessao(NomeCinema, "Os Implacáveis", _).


onde_assistir(NomeCinema) :- sessao(NomeCinema, "O Ocaso de uma Estrela", _).

Pergunta 11: Quais são os filmes em que “Woody Allen” aparece como
ator ou como diretor?

filmes_woody(NomeFilme) :- filme(NomeFilme, "Woody Allen", _).


filmes_woody(NomeFilme) :- filme(NomeFilme, _, "Woody Allen").

Pergunta 12: Que filmes em que “Woody Allen” é ator ou diretor estão
em cartaz em “The Monarch Theatre”?

filmes_woody(NomeFilme) :- filme(NomeFilme, "Woody Allen", _).


filmes_woody(NomeFilme) :- filme(NomeFilme, _, "Woody Allen").
em_cartaz(NomeFilme) :- sessao("The Monarch Theatre", NomeFilme, ) ,
filmes_woody(NomeFilme);

Pergunta 13: Liste todos os filmes que foram dirigidos por Hitchcock ou
que estão em cartaz em “Roxy Theatre”.

filme_escolhido(NomeFilme) :- filme(NomeFilme, "Hitchcock", _).


filme_escolhido(NomeFilme) :- sessao("Roxy Theatre", NomeFilme, _).

Pergunta 14: Liste todos os atores e diretores do filme “O Poderoso


Chefão”.

lista(NomePessoa) :- filme("O Poderoso Chef~


ao", NomePessoa, _).
lista(NomePessoa) :- filme("O Poderoso Chef~
ao", _, NomePessoa).

Observe que em todos estes casos, o que fizemos é equivalente a combinar


com uma operação de união o resultado de duas ou mais consultas conjuntivas.
Isso aumentou a expressividade das linguagens, sem precisar acrescentar nada
radicalemtne diferente das consultas que vimos neste capı́tulo.
44CAPÍTULO 2. LINGUAGENS DE CONSULTA E CONSULTAS CONJUNTIVAS
Capı́tulo 3

Adicionando Negação

As consultas conjuntivas, mesmo quando adicionamos união, ainda não são ca-
pazes de responder:
Pergunta 15: Quais os filmes dirigidos por Hitchcock em que o diretor não
atuou? Assuma que cada filme possui um só diretor.
Pergunta 16: Que filmes estão em cartaz no “Cine Barão”, mas não no
“Cinespacial”?
Pergunta 17: Liste os filmes nos quais todos os atores já participaram de
um filme de Hitchcock.
Para responder a este tipo de pergunta, devemos ser capazes de identificar
quando algo não acontece.
Se voltássemos no tempo até 1972 e mostrássemos o capı́tulo anterior para
Edgar Codd, primeiro ele ficaria feliz em saber que muitas décadas depois, as
suas ideias sobre bancos de dados tornaram-se a base do ensino. Observaria
com interesse os resultados teóricos de teoria da computação e teria interesse
em nossa prova de equivalência entre álgebra relacional, cálculo relacional e
outras linguagens de consulta. A informação de como seriam as linguagens SQL
e Datalog, que seriam criadas só alguns anos depois sria uma curiosidade vinda
do futuro para ele. Mas uma coisa que o deixaria intrigado seria termos limitado
tanto a proposta original dele.
“Veja bem, quando propus os bancos de dados relacionais, eu estava ciente do
cálculo de predicados e já haviam trabalhos anteriores que mostravam como ele
poderia ser usado para expressar consultas. Eu apresentei a álgebra relacional
como a minha contribuição para ser usado para criar linguagens de consulta
relacional, embora pelo que você me mostrou, as linguagens do futuro tem uma
notação bem diferente. Eu estou agora mesmo provando a equivalência entre
cálculo de predicados e álgebra relacional. Mas a álgebra relacional que eu
uso, assim como o cálculo relacional, não são tão limitados como os que você
apresentou. Eu não teria problemas nenhum em responder consultas sobre quais
filmes Hitchcock não atuou. Embora eu use os operadores ▷◁, π, σ, eu não tenho
nenhum problema em usar operações mais clássicas definidas sobre conjuntos
como a subtração, união e intersecção.”

45
46 CAPÍTULO 3. ADICIONANDO NEGAÇÃO

De fato, a hierarquia sobre os diversos tipos de consulta ainda não estavam


sendo estudados em 1972. Os primeiros resultados que mostraram que consultas
conjuntivas podiam ser otimizadas em bancos de dados de modo muito mais fácil
que outros tipos, só seria percebida cerca de 5 anos depois. Mas Codd, mesmo
em 1972 sabia bem que definir a negação em consultas de bancos de dados
precisava ser feito com cuidado. Quando ele apresentou a álgebra relacional,
não era difı́cil definir consultas negativas. Mas desafios apareceram no cálculo
relacional: como fazer uma consulta sobre um x ̸= 5 se podem haver infinitos
valores em que isso é verdade? Então, para satisfazer Coddd, poderı́amos apenas
responder que fizemos tal separação para tratar com mais cuidado o problema
da negação em um capı́tulo à parte.

3.1 Álgebra Relacional


Como Codd revelou na fala hipotética acima que nunca foi dita de verdade, a
álgebra relacional como foi proposta por ele não tinha problemas em responder
perguntas negativas. O segredo era lembrar que relações são conjuntos e que
poderı́amos usar a operação de subtração de conjuntos:
Pergunta 15: Quais os filmes dirigidos por Hitchcock em que o diretor não
atuou? Assuma que cada filme possui um só diretor.

πTı́tulo σDiretor = “Hitchcock” (F ) − σAtor = “Hitchcock” (F )
Pergunta 16: Que filmes estão em cartaz no “Cine Barão”, mas não no
“Cinespacial”?

πTı́tulo σCinema = “Cine Barão” (S) − σCinema = “Dinespacial” (S)
Pergunta 17: Liste os filmes nos quais todos os atores já participaram de
um filme de Hitchcock.

 

πTı́tulo (F ) − πTı́tulo πAtor (F ) − πAtor (σDiretor=“Hitchcock” (F )) ▷◁ F

3.2 Adicionando Negação ao Datalog


Na álgebra relacional, conseguimos expressar consultas envolvendo negação através
da subtração de conjuntos, e não precisamos nos preocupar muito com o que
isso significa: sabemos o que significa subtrair dois conjuuntos.
Datalog é uma linguagem de programação lógica, então quando definimos
algo nela, ou incrementamos a linguagem, acabamos com a responsabilidade
adicional de nos preocupar não só com regras de computação abstratas, mas
também com a semântica do quê estamos definindo.
O que significa a negação de uma relação?
Se conhecemos o fato:
3.2. ADICIONANDO NEGAÇÃO AO DATALOG 47

p(alguma_coisa).

Podemos fazer perguntas para Datalog prefixando o código com “?-”. O


programa nos retorna uma resposta para a consulta na linha abaixo:

?- p(alguma_coisa).
true.
?- p(outra_coisa).
false.

Dizemos que p(outra coisa) é falso porque esta é uma informação ca-
tegórica, sobre a qual temos certeza de sua falsidade (negação lógica) ou
dizemos que é falso pelo fato de não existir algo que nos diga que é verdadeiro
(negação por falha)? Se perguntássemos para Datalog:

?- existe(cisne_negro).
true.

O que está ocorrendo é que Datalog está nos dizendo que encontrou um cisne
negro, isto é, conseguiu encontrar uma forma de avaliar existe(cisne negro)
de modo que a relação é verdadeira. Note que “eu encontrei um cisne negro” é
algo que podemos considerar como sinônimo de “existe um cisne negro”, já que
encontrar um prova sua existência.
Por outro lado, se perguuntássemos para Datalog:

?- existe(cisne_negro).
false.

Então Datalog está nos dizendo que não encontrou um cisne negro. Não
havia o fato existe(cisne negro) armazenado em seu sistema, e tampouco tal
fato pode ser deduzido pelas regras conhecidas. Entretanto, “eu não encontrei
um cisne negro” não é a mesma coisa que “não existem cisnes negros”. À partir
do momento que lidamos com negação, então estamos introduzindo em nossas
respostas para consultas cisnes negros, e é importante sabermos se eles estão
sendo introduzidos porque não existem, ou porque não foram encontrados.
Se temos um conjunto de relações que representa uma teoria completa sobre
algo, então neste caso especı́fico, se não for encontrado, então não existe. Por
exemplo, se um banco de dados se propõe a armazenar todas as informações
existentes sobre um conjunto de cartas colecionáveis produzida especificamente
no ano de 2020, então pode ser possı́vel completar ele com informações completas
que nunca mais precisarãos er atualizadas. Se uma relação não for encontrada,
neste caso podemos dizer que ela não existe e que não encontrar algo é o mesmo
que a não existência. Mas em bancos de dados incompletos, que são atualizados
com mais informações sobre o mundo, então a falha em encontrar algo não
significa que algo não existe.
Como representar a negação lógica é praticamente impossı́vel para Datalog,
o tipo de negação com a qual o sistema lida é a negação por falha. Nem todas
48 CAPÍTULO 3. ADICIONANDO NEGAÇÃO

as implementações de Datalog suportam negação. Mas quando suportam, o


operador que representa a negação por falha é o \+:
Pergunta 15: Quais os filmes dirigidos por Hitchcock em que o diretor não
atuou?
resposta(X) :- filme(X, "Hitchcock", _) ,
\+ filme(X, _, "Hitchcock").
Isso produz os filmes nos quais encontramos Hitchcock como sendo o diretor,
mas não o encontramos entre os atores.
Pergunta 16: Que filmes estão em cartaz no “Cine Barão”, mas não no
“Cinespacial”?
resposta(X) :- sessao("Cine Bar~
ao", X, _) ,
\+ sessao("Cinespacial", X, _).
Pergunta 17: Liste os filmes nos quais todos os atores já participaram de
um filme de Hitchcock.
ator_hitchcock(NomeAtor) :- filme(_, "Hitchcock", NomeAtor).
resposta_negada(NomeFilme) :- filme(NomeFilme, _, NomeAtor) ,
\+ ator_hitchcock(NomeAtor).
resposta(NomeFilme) :- filme(NomeFilme, _, _) ,
\+ resposta_negada(NomeFilme).
Note qua a relação resposta negada definida acima lista todos os filmes que
possuem ao menos um ator que não atuou em um filme de Hitchcock. E é esta
lista de filmes que é filtrada fora para produzir a resposta final.
Muito cuidado deve ser tomado em consultas com negação, pois elas tendem
a ser menos intuitivas. Por exemplo, esta seria uma consulta incorreta para a
pergunta 17 acima:
resposta_negada(NomeFilme) :- filme(NomeFilme, _, NomeAtor) ,
\+ filme(AlgumFilme, "Hitchcock", NomeAtor),
filme(AlgumFilme, "Hitchcock", _).
resposta(NomeFilme) :- filme(NomeFilme, _, _) ,
\+ resposta_negada(NomeFilme).
A resposta negada neste caso lista todos os filmes em que cada ator não atuou
em algum filme de Hitchcok. Portanto, a resposta final é a lista de filmes em que
todos os atores atuaram em todos os filmes de Hitchcock. O fato de termos uma
variável não-anônima faz toda a diferença: subitamente não estamos falando de
qualquer filme, mas de algum filme especı́fico. Naturalmente, nem sempre as
variáveis terão nomes adequados mostrando isso.
Outra coisa a se lembrar é que as regras do Datalago, tais como as estamos
apresentando, no momento não permitem recursão. Embora possamos definir
novas relações por meio de regras de consulta, não é oermitido que qualquer
tiopo de definição circular apareça. Portanto, o seguinte código não estamos
considerando como exemplo de código válido:
3.3. CÁLCULO RELACIONAL 49

consulta1(a, b) :- R(a, b, X), S(x, 1), consulta2(b).


consulta2(a) :- consulta1(a, 5).

3.3 Cálculo Relacional


Adicionar negação ao Cálculo Relacional torna ele muito semelhando à lógica
de primeira ordem, exceto por ele não permitir o uso de funções nas regras.
Contudo, esta flexibilidade faz também com que seja mais difı́cil definir como
usar negação sem que haja a possibilidade de obtermos um número infinito
de respostas em certas consultas. Evitar isso signitica tentar tornar o cálculo
relacional “seguro”.
Primeiro vamos definir mais formalmente o que é uma fórmula bem-formada
de cálculo relacional. Seja um banco de dados R, no qual existem as relações
R1 , . . . , Rn , podemos dizer que as fórmulas de cálculo relacional sobre eles são:

1. Ri (a1 , . . . , am ) é uma fórmula bem-formada caso Ri seja uma relação de


R de aridade m e caso cada um dos termos a1 , . . . , am sejam variáveis ou
constantes. Cada variável em um átomo é inicialmente considerada uma
variável livre.

2. e = e′ é uma fórmula bem-formada se e e e′ são variáveis ou constantes.


Se variáveis, elas são variáveis livres.

3. e ̸= e′ é uma fórmula bem-formada se e e e′ são variáveis ou constantes.


Caso sejam variáveis, são variáveis livres.

4. (ϕ ∧ ψ) é fórmula bem-formada se ϕ e ψ também são fórmulas bem-


formadas. As variáveis da fórmula são consideradas livres se eram livres
em ϕ e em ψ (ambos).

5. (ϕ ∨ ψ) é fórmula bem-formada se ϕ e ψ também são fórmulas bem-


formadas. As variáveis da fórmula são consideradas livres se eram variáveis
livres em ϕ ou em ψ (qualquer um dos dois).

6. ¬ϕ é fórmula bem-formada se ϕ é bem-formada.

7. ∃xϕ é uma fórmula bem-formada onde x é uma variável e ϕ é outra fórmula


bem-formada. Consideramos então que na fórmula a variável x se torna
uma variável ligada (e não mais livre). As demais variáveis são livres
caso sejam livres em ϕ.

8. ∀xϕ é uma fórmula bem-formada onde x é uma variável e ϕ é outra fórmula


bem-formada. Novamente, passamos a considerar a variável x como sendo
uma variável ligada (por estar ligada a um quantificador), e as demais são
variáveis livres caso sejam livres em ϕ.

Podemos abreviar construções como ∃x1 , . . . , ∃xn e ∀x1 , . . . , ∀xn escrevendo


apenas ∃x1 , . . . , xn e ∀x1 , . . . , xn .
50 CAPÍTULO 3. ADICIONANDO NEGAÇÃO

É possı́vel também adicionar operações como → e ↔, que significam:

(ϕ → ψ) ≡ ¬ϕ ∨ ψ

(ϕ ↔ ψ) ≡ (ϕ ∧ ψ) ∨ (¬ϕ ∧ ¬ψ)
Uma consulta em cálculo relacional tem a forma {⟨e1 , . . . , en ⟩|ϕ} onde ϕ é
uma fórmula onde todo e1 , . . . , en é uma variável livre em ϕ (podendo haver
repetição) ou é uma constante.
Tendo especificado as regras sintáticas para as consultas em cálculo rela-
cional, podemos então criar consultas para responter às perguntas envolvendo
negação.
Pergunta 15: Quais os filmes dirigidos por Hitchcock em que o diretor não
atuou? Assuma que cada filme possui um só diretor.

{⟨xt ⟩|∃xa F (xt , “Hitchcock”, xa ) ∧ ¬F (xt , “Hitchcock”, “Hitchcock”)}

Pergunta 16: Que filmes estão em cartaz no “Cine Barão”, mas não no
“Cinespacial”?

{⟨xt ⟩|∃xa , xb S(“Cine Barão”, xt , xa ) ∧ ¬S(“Cinespacial”, xt , xb )}

Pergunta 17: Liste os filmes nos quais todos os atores já participaram de
um filme de Hitchcock.

{⟨xt ⟩|∃xd , xa F (xt , xd , xa ) ∧ ∀ya (∃yd F (xt , yd , ya ) → ∃zt F (zt , “Hitchcock”, ya ))}

A primeira parte da conjunção garante que a variável xt irá percorrer todos


os valores possı́veis de tı́tulos de filmes na relação F existente. A segunda parte
garante as condições existente para os atores do filme. Note que podemos facil-
mente escrever ∀ya para representar todos os atores de cada filme e especificar
a condição que eles devem ter sido dirigidos por Hitchcock usando um →. Não
usamos negação explicitamente, mas ela está implı́cita no operador “→”.
Contudo, a expressividade do cálculo relacional também nos trás:

{⟨x⟩|¬F (“Woodstock”, “Michael Wadleigh”, x)}


A consulta acima nos trás todo x que não participou do documentário “Wo-
odstock”. Mas o quê é x? Será que x poderia incluir também filmes, o número 5
e sessões de cinema? Afinal, nenhuma destas coisas participou do documentário.
Esta seria a interpretação que seguiria a semântica mais tradicional do cálculo
de predicados. É também chamada de interpretação não relativizada, pois não
estamos assumindo que os elementos de uma consulta só podem ser valorados
em relação a algum domı́nio estabelecido.
3.3. CÁLCULO RELACIONAL 51

Como esta é uma forma ampla demais para conseguirmos tratar a negação,
uma forma então seria usar uma interpretação relativizada, determinando domı́nios
que podem ser usados para valorar as variáveis livres da fórmula de uma con-
sulta. No caso da fórmula acima, se o último termo da relação F é uma string,
isso então poderia significar que qualquer string pode ser usada (mas não coisas
que nçao são strings). Ou devı́amos nos restringir ao conjunto de atores? Qual-
quer ator que venha a existir ou que já existiu? A solução mais adequada seria
usar como escolha o conjunto de domı́nio associado à cada termo de cada relação
armazenado no banco de dados. Esta é a chamada interpretação natural (ou
irrestrita) das consultas no cálculo relacional. Note que podemos neste caso
encontrar domı́nios infinitos em nossas consultas, e isso torna o resultado da
consulta indefinido. A consulta acima, por exemplo, seria indefinida.
Outra solução tentadora seria restringir o domı́nio de modo que somente
elementos de πAtor (F ) pudessem ser considerados como elementos válidos da
consulta acima. Ou, para definir de maneira mais geral, o domı́nio ativo de
cada termo de relação em um banco de dados é a soma de todos os valores cons-
tantes que são encontrados naquele termo de uma dada relação. Já o domı́nio
ativo de uma consulta são todas as constantes que aparecem na consulta asso-
ciadas a cada termo de cada relação. Ao avaliar quais as valorações possı́veis
para um termo com uma variável livre na fórmula, poderı́amos nos restringir
somente à valores do domı́nio ativo, tanto do banco de dados, como da con-
sulta que estão associados àquele termo. Esta é a interpretação de domı́nio
ativo das consultas de cálculo relacional. Nesta interpretação a consulta acima
pode ser satisfeita e produz todas as pessoas registradas no banco de dados que
participaram de um filme, mas não no filme “Woodstock” dirigido por Michael
Wadleigh.
Por fim, em algumas consultas, poderı́amos ainda especificar outros conjun-
tos possı́veis que poderiam ser usados para valorar cada variável livre presente
em determinados termos de uma relação. Estes conjuntos necessariamente de-
vem conter o domı́nio ativo e o domı́nio natural delas devem contê-los. Dizemos
entao que a consulta deve ser avaliada em relação a um domı́nio explı́cito D.
Outro exemplo de consulta problemática usando disjunção:

{⟨x, y⟩|F (“Woodstock”, “Michael Wadleigh”, x)∨F (y, “Michael Wadleigh”, “Janis Joplin”)}

Um exemplo semelhante havia sido apontado no capı́tulo anterior como po-


tencial fontes de problemas. Na disjunção acima, o primeiro termo atômico
F (“Woodstock”, “Michael Wadleigh”, x) define os valores possı́veis para x, mas
o valor de y pode ser qualquer valor possı́vel. O segundo define um valor para
y, mas o valor de x pode ser qualquer um. Se usarmos a interpretação natural,
a consulta poderia ser idefinida se o primeiro ou terceiro termo de F puder ser
valores de um domı́nio infinito. Mesmo na interpretação de domı́nio ativo, todas
as tuplas do banco de dados seriam inseridas como resposta para a consulta.
Outra consulta problemática caso estejamos sob a interpretação natural com
conjuntos infinitos é:
52 CAPÍTULO 3. ADICIONANDO NEGAÇÃO

{⟨x⟩|∀yR(x, y)}

Executar esta consulta evitando laços infinitos pode ser feito dependendo do
caso, mas é algo intrincado.
E finalmente:

{⟨xt ⟩|∀ya (∃yd F (xt , yd , ya ) → ∃zt F (zt , “Hitchcock”, ya ))}

A consulta acima, para todo diretor ator ya encontra os seus diretores e


mantém aqueles que já foram dirigidos por Hitchcock. Contudo, como A → B
é verdadeiro também quando A é falso, a consulta também produz todos os
nomes de filme do domı́nio que não aparecem na relação F . No domı́nio ativo,
isso não é nenhum resultado a mais, no domı́nio natural, podem haver nomes
de filmes adicionais.
Como pode-se observar, um problema deste tipo de consulta seria que ela não
é independente do domı́nio. Dependendo de como definimos o domı́nio de acordo
com nossa interpretação, o resultado pode ser completamente diferente. Esta é
uma propriedade problemática, pois agora o resultado potencial de uma consulta
não está mais inteiramente sob controle de quem está fazendo tal consulta, mas
também sob controle de como o banco foi definido, ou então do quão completo
ele é. Uma consulta que sempre gera o mesmo resultado, independente do
domı́nio escolhido, é uma consulta independente de domı́nio. É o caso das
consultas que usamos para responder às perguntas 15, 16 e 17. As demais que
mostramos serem problemáticas, não são independentes de domı́nio. Se uma
consulta produz o mesmo resultado tanto sob a interpretação natural como sob
a interpretação do domı́nio ativo, então ela é independente de domı́nio.

3.4 Negação em SQL


A linguagem SQL permite que possamos subtrair o resultado de uma consulta
de outra. O que funciona como a subtração de conjuntos vista na álgebra re-
lacional. A subtração é feita usando o operador binário EXCEPT. Além disso,
a linguagem SQL também suporta usar, além de igualdades, comparações en-
volvendo desigualdades. Podemos escrever A <> B para dizer que A e B são
diferentes. Ou, podemos escrever o sinônimo NOT (A = B).
Outro recurso que pode ser usado é colocar como condição na consulta que
o resultado de uma outra consulta não existe por meio de NOT EXIST.
Pergunta 15: Quais os filmes dirigidos por Hitchcock em que o diretor não
atuou?

SELECT TITULO FROM FILMES WHERE DIRETOR=’Hitchcock’


EXCEPT
SELECT TITULO FROM FILMES WHERE ATOR=’Hitchcock’;
3.5. EQUIVALÊNCIA ENTRE DIFERENTES MODELOS COM NEGAÇÃO53

A consulta acima funciona como a subtração de conjuntos e assim como


outras operações definidas sobre conjuntos (tal como a UNION), ela também
instrui o SQL a remover qualquer resultado repetido.
Pergunta 16: Que filmes estão em cartaz no “Cine Barão”, mas não no
“Cinespacial”?

SELECT TITULO FROM SESSOES WHERE CINEMA=’Cine Bar~


ao’
EXCEPT
SELECT TITULO FROM SESSOES WHERE CINEMA=’Cinespacial’;

Pergunta 17: Liste os filmes nos quais todos os atores já participaram de
um filme de Hitchcock.
Este é um caso no qual não é possı́vel expressar a consulta somente por
meio de subtração de conjuntos. Expressar desigualdades na cláusula WHERE
tampouco nos ajuda, pois SELECT DISTINCT a.TITULO FROM FILME a, FILME
b WHERE a.ATOR=b.ATOR AND b.DIRETOR <> ’Hitchcock’; apenas nos retor-
naria os filmes nos quais há ao menos um ator queparticipou de um filme que
não é do Hitchcock.
Este é um caso no qual a forma mais simples de resolver é usar a condição
de que não existe resultado para uma subconsulta:

SELECT TITULO FROM FILMES


EXCEPT
SELECT a.TITULO FROM FILMES a
WHERE NOT EXISTS
(SELECT 1 FROM FILMES b WHERE a.ATOR=b.ATOR AND b.DIRETOR=’Hitchcock’);

A consulta anterior gera duas consultas e as subtrai. A primeira delas é o


conjunto de todos os filmes e a segunda é o conjunto de todos os filmes onde
existe um ator que nunca participou de um filme de Hitchcock. Descobrimos se
um ator nunca participou fazendo a consulta e verificando se o resultado existe.

3.5 Equivalência entre Diferentes Modelos com


Negação
Teorema 7. O Cálculo Relacional com consultas disjuntivas e com negação
é tão ou mais expressivo que a álgebra relacional com união e subtração de
conjuntos.
Demonstração. No Teorema 1 já mostramos que isso é verdade quando não
consideramos disjunções e negações. Temos apenas que partir daquela prova,
acrescentando os casos novos, mostrando que ela continua válida com eles.
Para isso, só precisamos mostrar como criar uma fórmula de cálculo rela-
cional equivalente à duas expressões de álgebra sob união e sob subtração, e
assumindo que temos a fórmula de cálculo relacional destas duas sub-fórmulas.
Fazemos isso abaixo:
54 CAPÍTULO 3. ADICIONANDO NEGAÇÃO

1. Se temos uma fórmula F1 ∪ F2 entre duas fórmulas algébricas F1 e F2 que


possuem ambas as seguintes representações em cálculo relacional:

{⟨e1 , . . . , em ⟩|∃x1 , . . . xk (R1 (u1 ) ∧ . . . ∧ Rn (un ))}

{⟨e′1 , . . . , e′m ⟩|∃x′1 , . . . x′k′ (R1′ (u′1 ) ∧ . . . ∧ Rn′ ′ (u′n′ ))}

A união só pode ocorrer se a aridade de F1 e F2 forem iguais e elas repre-


sentarem os mesmos tipos de termos. Portanto, a fórmula que representa
a união pode ser montada assim:

{⟨e1 , . . . , em ⟩|∃x1 , . . . xk , x′1 , . . . x′k (R1 (u1 ) ∧ . . . ∧ Rn (un ))∨(R1′ (u′1 ) ∧ . . . ∧ Rn′ ′ (u′n′ )) }


O único cuidado a se tomar é que as variáveis da primeira fórmula de


cálculo não devem conflitar com as variáveis da segunda (se necessário,
deve-se mudar o nome das variáveis para evitar conflito) e cada e′i ∈
{e′1 , . . . , e′m } deve ser substituı́da na fórmula final pela variável corres-
pondente de {e1 , . . . , em } caso e′i e ei forem variáveis. Se ao menos uma
delas for uma constante C, então usamos uma variável ei para substituir
a constante e adicionamos uma cláusula . . . ∧ (ei = C) no termo disjuntivo
correspondente à parte em que estava a constante.
Note que qualquer fórmula construı́da desta forma, temos a garantis de
que todas as variáveis do cabeçalho (e1 , . . . , em ) aparecem cada termo da
disjunção. Por isso, não é possı́vel obter assim uma fórmula que não é in-
dependente de domı́nio, tal como {⟨e1 , e2 ⟩|∃x1 , x2 (R(e1 , x1 ) ∨ R(x2 , e2 ))}.

2. Se temos uma fórmula F1 −F2 onde F1 e F2 são duas expressões de álgebra


relacional para as quais conhecemos fórmula de cálculo relacional equiva-
lente cuja forma é a mesma do caso acima, então podemos combinar ambas
as fórmulas para gerar uma fórmula de cálculo relacional representando
F1 − F2 :

{⟨e1 , . . . , em ⟩|∃x1 , . . . xk , x′1 , . . . x′k R1 (u1 )∧. . .∧Rn (un )∧¬R1′ (u′1 )∧. . .∧¬Rn′ ′ (u′n′ ) }


Assumimos no caso anterior que F1 e F2 tem a mesma aridade, portanto,


subtraindo de F1 podemos obter um conjunto diferente. Caso elas tenham
uma aridade diferente, F1 − F2 = F1 e simplesmente usamos a fórmula de
F1 para representar a consulta. E assim como no caso anterior, assumimos
que as variáveis x1 , . . . xk são todas diferentes de x′1 , . . . , x′k′ . Caso não fo-
rem, basta trocarmos nomes das variáveis para que não haja mais conflito.
Também mudamos o nome de todas as variáveis e′i para ei assumindo que
ambas são variáveis. Se uma delas for constante, a outra é quem muda de
3.5. EQUIVALÊNCIA ENTRE DIFERENTES MODELOS COM NEGAÇÃO55

valor para ser a mesma constante. E se ambas forem constantes, mas com
valores diferentes, então já sabemos que F1 e F2 são disjuntos e caı́mos de
novo no caso em que F1 − F2 = F1 e podemos apenas usar a fórmula de
F1 .
Observe que seguindo a regra acima, não há como produzir uma fórmula
onde uma variável ei aparece em uma relação negada, mas não aparece em
uma relação não-negada. A relação não-negada funciona então como um
limitador de quais são os valores que ei pode ter, e à partir destes valores,
a relação negada pode remover alguns destes elementos finitos. Com isso,
se as fórmulas de F1 e F2 forem independentes de domı́nio, a fórmula de
F1 − F2 obtida acima também será independente de domı́nio.
Portanto, conseguimos demonstrar que qualquer expressão de álgebra rela-
cional pode ser convertida para uma fórmula de cálculo relacional (e tal fórmula
será independente de domı́nio).
Teorema 8. O cálculo relacional com disjunção e negação é igualmente ex-
pressivo quando restrito à consultas independente de domı́nio e quando sob a
interpretação de domı́nio ativo.
Demonstração. Toda consulta independente de domı́nio já é uma consulta sob
a interpretação de domı́nio ativo, pois ela irá produzir o mesmo resultado, in-
dependente de como o domı́nio é definido.
Por outro lado, cada consulta sob interpretação de domı́nio ativo pode
também ser convertido para uma consulta independente de domı́nio. Basta
modificar a consulta para que a interpretação de domı́nio ativo seja represen-
tada dentro da própria consulta. Por exemplo, assuma que uma negação ou
disjunção possui uma variável x que na interpretação de domı́nio ativo corres-
ponde a valores associados a um termo de uma relação R mais a uma lista de
constantes c1 , . . . , ci . Se modificarmos a consulta acrescentando a conjunção
∧ R(. . . , x, . . .) ∨ x = c1 ∨ . . . ∨ x = ci , então toda interpretação será idêntica
à interpretação de domı́nio ativo e assim a consulta se torna independente de
domı́nio.
Teorema 9. A álgebra relacional é tão ou mais expressiva quanto o cálculo
relacional sob a interpretação do domı́nio ativo.
Demonstração. A versão do cálculo relacional apresentado aqui é muito mais
elaborado e completo que a versão do capı́tulo anterior usando apenas consulta
conjuntiva. Desta forma, a única forma de provar a afirmação é por meio da
análise sintática das fórmulas bem-formadas que apresentamos, mostrando como
podemos usar elas para construir expressões algébricas equivalentes. A fórmula
deve ser interpretada assumindo que uma árvore sintática foi construı́da e a
expressão algébrica correspondente é obtida à partir de regras recursivas que
vão produzindo expressões intermediárias e também um contexto de tradução.
O contexto de tradução é uma lista de possı́veis relações de equivalência
e diferença entre variáveis e constantes. Cada elemento desta lista é uma tu-
pla onde o primeiro elemento é um conjunto de classes de equivalência entre
56 CAPÍTULO 3. ADICIONANDO NEGAÇÃO

variáveis e constantes e o segundo elemento é um conjunto de pares de variáveis


e constantes que sabemos serem diferentes entre si. À medida que produzimos
a nossa fórmula, podem haver vários elementos no no contexto de tradução:
as disjunções fazem com que tenhamos várias possibilidades de classes de equi-
valência e de relações de diferença que podem ser satisfeitas.
Podemos juntar dois contextos de tradução. Fazer isso significa unir to-
dos os elementos do primeiro contexto com cada um dos elementos do segundo
contexto. Unir dois elementos significa juntar suas classes de equivalência, possi-
velmente colapsando duas ou mais classes em uma só caso exista transitividade
entre seus elementos. Já o conjunto de relação de diferença entre variáveis e
constantes apenas é unido. O elemento resultante é inválido se ele armazenou
algo como x ̸= x na lista de diferenças, ou ele colocou duas constantes diferen-
tes na mesma classe de equivalência, ou então ele produziu x ̸= y tal que x e
y pertencem à mesma classe de equivalência. Elementos inválidos são sempre
removidos da união de contextos de tradução. Em uma fórmula, cada elemento
do contexto de tradução está associado ao elemento de uma disjunção, e quando
o elemento é removido do contexto, sua fórmula associada é removida também.
Se todos os elementos do contexto de tradução de uma fórmula forem removidos,
a expressão algébrica equivalente à ela é simplesmente o conjunto vazio ∅.
Ao fim, após gerar a expressão algébrica da fórmula bem-formada, deve-se
considerar o cabeçalho da fórmula que estabelece a ordem e quantidade em que
cada variável livre deve aparecer no resultado da consulta. Isso é facilmente
obtido por meio de uma projeção (π).
As regras recursivas para traduzirmos são:

1. A fórmula atômica composta pela relação Ri (a1 , . . . , am ) é representada


na álgebra relacional simplesmente por Ri caso todos os termos forem
variáveis. Para cada termo i que tiver um valor constante Ci , aplicamos
um σi=Ci para selecionar somente elementos de Ri que tenham os valo-
res constantes
 da fórmula. O contexto de tradução é então inicializado
como (∅, ∅) , sem nenhuma classe de equivalência ou relação de diferença
conhecida.
Exemplo (ignorando mudança de nomes das colunas):


{⟨e1 , e2 ⟩|F (e1 , “Barbara Loden”, e2 )} ⇔ πTitulo, Ator σDiretor=“Barbara Loden” (F )

2. Caso tenhamos a fórmula atômica e = e′ , se ambos forem constantes, a


fórmula é traduzida como ∅, não produzindo qualquer resposta, já que não
há variáveis livres na fórmula. Se um deles for uma variável e o outro uma
constante, então o resultado da consulta à esta fórmula é simplesmente
R(c) onde R é uma nova relação com um só elemento de aridade 1 corres-
pondente ao valor constante. Por fim, se ambos os valores forem variáveis,
como são variáveis livres, a expressão de álgebra relacional equivalente
é a que usa projeção (π) para selecionar individualmente todas colunas
de cada relação e deixar o resultado em duas colunas, onde a segunda
3.5. EQUIVALÊNCIA ENTRE DIFERENTES MODELOS COM NEGAÇÃO57

coluna é idêntica à primeira. Em seguida, ela une todos eles usando a


união (∪). O resultado é uma lista com todos os valores armazenados no
banco de dados, onde cada um deles aparece redundantemente duas vezes
na sua relação (pois cada um deles é igual a si mesmo). As duas colunas
da relação resultante são nomeadas usando os nomes das variáveis usa-
das. O contexto de tradução desta fórmula é ({{e, e′ }}, ∅) , produzindo
a primeira classe de equivalência contendo e e e′ .
Exemplos:

{⟨e1 , e2 ⟩|e1 = e2 } ⇔ πTitulo, Titulo (F ) ∪ πDiretor, Diretor (F ) ∪ . . .

{⟨e1 ⟩|e1 = 5} ⇔ R(5)

3. Para a fórmula atômica e ̸= e′ , se ambos forem constantes, a fórmula


é traduzida como ∅, não produzindo qualquer resposta, já que não há
variáveis livres na fórmula. Se um deles for uma variável e o outro uma
constante c, nós produzimos um conjunto de todos os valores que temos
no banco de dados em qualquer coluna (isso pode ser feito através da
união de projeções como mostrado no caso anterior) e subtraı́mos deste
conjunto a relação com um único elemento R(c). Se ao invés disso nós
tivermos uma desigualdade entre duas variáveis, nós podemos produzir
uma consulta equivalente a isso produzindo uma relação de aridade 1
com todas as constantes armazenadas no banco de dados, realizando o
produto cartesiano desta relação consigo mesma (o produto cartesiano é
obtido com o ▷◁ após mudarmos os nomes das colunas para que os dois
operandos não tenham colunas com o mesmo nome) e subtraindo desta
relação a expressão equivalente a {⟨e1 , e2 ⟩|e1 = e2 } vista acima. Os nomes
das colunas são então mudados para refletir os nomes das variáveis que as
representam. O contexto de tradução para esta fórmula é (∅, {{e, e′ }}) ,


armazenando a relação de diferença entre e e e′ .


Exemplos:


{⟨e1 ⟩|e1 ̸= 5} ⇔ πTitulo (F ) ∪ πDiretor (F ) ∪ . . . − {⟨5⟩}

 
{⟨e1 ⟩|e1 ̸= e2 } ⇔ πTitulo (F )∪πDiretor (F )∪. . . × πTitulo (F )∪πDiretor (F )∪. . . −{⟨e1 , e2 ⟩|e1 = e2 }

4. Para fórmulas não-atômicas F1 ∧ F2 onde F1 e F2 são fórmulas bem-


formadas para as quais conhecemos expressão algébrica correspondente e
temos o contexto de tradução, nós começamos gerando um novo contexto
de tradução, juntando todas as possibilidades de F1 com as de F2 (se não
encontramos disjunção, só há uma possibilidade de contexto em ambas
as fórmulas). Em seguida, para cada possibilidade de contexto obtida,
58 CAPÍTULO 3. ADICIONANDO NEGAÇÃO

geraremos uma expressão algébrica que será unida às demais por meio
de união (∪). Cada expressão individual é obtida à partir da mudança de
nomes das colunas de F1 e F2 de modo que se ambas tiverem variáveis per-
tencentes à mesma classe de equivalência, elas devem passar a ter colunas
com o mesmo nome. Após realizar a mudança de nome, é feita a junção
natural entre as expressões algébricas correspondentes à F1 e F2 . Por fim,
para cada relação de equivalência, se houver uma variável resultante equi-
valente a uma constante, usamos a seleção σ para manter somente valores
em que a coluna correspondente à ela tenha tal valor constante.
5. Para fórmulas não-atômicas F1 ∨ F2 onde F1 e F2 são fórmulas bem-
formadas com os respectivos contextos de tradução C1 e C2 , começamos
produzindo um novo contexto de tradução concatenando C1 e C2 e produ-
zindo a união da expressão algébrica correspondente à F1 com a expressão
correspondente à F2 . Observe que seguindo todas as regras vistas até
agora, o número de operandos de operações de disjunções que temos é
sempre igual ao número de elementos do contexto de tradução. Cada
operando possui o seu elemento da lista.

Você também pode gostar

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy