Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.

Prévia do material em texto

C. J. Date
Novatec
SQL e 
Teoria Relacional
Como escrever códigos SQL precisos
Authorized Portuguese translation of the English edition of titled SQL and Relational Theory 2E ISBN 
9781449316402 © 2012 C. J. Date. This translation is published and sold by permission of O'Reilly Media, 
Inc., the owner of all rights to publish and sell the same.
Tradução em português autorizada da edição em inglês da obra SQL and Relational Theory 2E ISBN 
9781449316402 © 2012 C. J. Date. Esta tradução é publicada e vendida com a permissão da O'Reilly Media, 
Inc., detentora de todos os direitos para publicação e venda desta obra.
© Novatec Editora Ltda. [2015].
Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. 
É proibida a reprodução desta obra, mesmo parcial, por qualquer processo, sem prévia autorização, por escrito, 
do autor e da Editora.
Editor: Rubens Prates
Tradução: Rafael Zanolli
Revisão técnica: Edgard Damiani / Rodrigo Stulzer
Revisão gramatical: Marta Almeida de Sá
Editoração eletrônica: Carolina Kuwabata
Assistente editorial: Priscila A. Yoshimatsu
ISBN: 978-85-7522-433-5 MP20150506
Histórico de impressões:
Maio/2015 Primeira edição
Novatec Editora Ltda.
Rua Luís Antônio dos Santos 110
02460-000 – São Paulo, SP – Brasil
Tel.: +55 11 2959-6529
Fax: +55 11 2950-8869
Email: novatec@novatec.com.br
Site: www.novatec.com.br
Twitter: twitter.com/novateceditora
Facebook: facebook.com/novatec
LinkedIn: linkedin.com/in/novatec
Nutshell Handbook, o logotipo Nutshell Handbook e o logotipo da O’Reilly são marcas registradas da O’Reilly 
Media, Inc. 
SQL e Teoria Relacional: Como Escrever Códigos SQL Precisos e os elementos comerciais relacionados são 
marcas registradas da O’Reilly Media, Inc.
Muitas das designações usadas por fabricantes e vendedores para distinguir seus produtos são marcas regis-
tradas. Nos locais em que termos desse tipo foram utilizados neste livro, estando a O’Reilly Media, Inc. ciente 
da existência de uma marca registrada, as designações foram escritas em letras maiúsculas ou com a letra 
inicial maiúscula.
Ainda que todas as precauções tenham sido tomadas na preparação deste livro, a editora e os autores não se 
responsabilizam por erros, omissões ou danos que resultem do uso das informações contidas neste texto.
23
capítulo 1
Preparando o cenário
Senta-te pacientemente, minha alma; 
Não julgues antes de apresentada a peça;
Seu enredo tem muitas variações; cada dia 
Traz uma nova cena; o último ato coroa a peça.
– Francis Quarles: Emblemas (1635)
Uma abordagem relacional à linguagem SQL: esse é o tema – ou um dos temas – 
deste livro. Evidentemente, para tratar de tal tópico adequadamente, preciso abordar 
questões relacionais assim como questões de SQL em si – e ainda que essa afirmação 
obviamente se aplique ao livro como um todo, ela se aplica ao primeiro capítulo com 
força especial. Em consequência, este capítulo tem comparativamente pouco a dizer 
sobre SQL como tal. O que desejo fazer é revisar material que, na sua maior parte, 
espero que, de qualquer maneira, você já conheça. Minha intenção é estabelecer um 
ponto de partida como tal: em outras palavras, estabelecer algumas bases sobre as 
quais o restante do livro possa ser construído. No entanto, ainda que eu espere que 
você esteja familiarizado com a maioria do que tenho a dizer neste capítulo, gostaria 
de sugerir, respeitosamente, que você não o pule. Você precisa saber o que precisa 
saber (se entende o que eu quero dizer); mais especificamente, você precisa ter certeza 
de que tem os pré-requisitos necessários para compreender o material que virá nos 
capítulos futuros. Na realidade, gostaria de recomendar educadamente que, ao longo 
deste livro, você não pule a discussão de algum assunto só porque acredita que já 
esteja familiarizado com o tópico. Por exemplo, você tem certeza de que sabe o que 
é uma chave, em termos relacionais? Ou uma junção?1
1 Existe pelo menos um especialista que não sabe. A seguir temos uma citação direta de um docu-
mento que afirma (como este livro!) oferecer conselhos para usuários SQL: “Não utilize junções 
... Oracle e SQL Server têm abordagens fundamentalmente diferentes sobre esse conceito ... Você 
pode terminar com conjuntos de resultado inesperados ... Você deve compreender os tipos básicos 
de cláusulas de junções ... Junções equivalentes são formadas recuperando todos os dados de 
duas fontes distintas e combinando-os em uma grande tabela ... Junções internas são feitas nas 
colunas internas de duas tabelas. Junções externas são feitas nas colunas externas de duas tabelas. 
Junções à esquerda são feitas nas colunas à esquerda de duas tabelas. Junções à direita são feitas 
nas colunas à direita de duas tabelas.”
SQL e Teoria Relacional24
O modelo relacional é muito mal-compreendido
Profissionais em qualquer disciplina precisam conhecer os fundamentos de seu 
campo. Por isso, se você é um profissional de bancos de dados, precisa conhecer o 
modelo relacional, pois o modelo relacional é a base (ou uma grande parte da base, 
de qualquer modo) do campo dos bancos de dados em particular. Agora, todo curso 
em gerenciamento de bancos de dados, seja ele acadêmico ou comercial, realmente 
manifesta pelo menos a ideia de ensinar o modelo relacional – mas a maioria desse 
ensino parece ser feita de modo muito equivocado, se tivermos por base os resultados. 
Certamente, o modelo não é bem entendido pela comunidade de bancos de dados 
como um todo. Aqui estão alguns dos possíveis motivos para essa situação atual:
•	 O	modelo	é	ensinado	em	um	vácuo.	Ou	seja,	pelo	menos	para	principiantes,	é	
difícil ver a relevância do material, entender os problemas que ele deve resolver, 
ou ambos.
•	 Os	próprios	 instrutores	não	 entendem	completamente	ou	não	 apreciam	a	
significância do material.
•	 Talvez,	mais	provavelmente	na	prática,	o	modelo	não	seja	sequer	ensinado	–	a	
linguagem SQL, ou algum dialeto específico dessa linguagem, como o dialeto 
Oracle, é ensinado em vez disso.
Então este livro é direcionado aos praticantes de bancos de dados em geral, e aos pra-
ticantes de SQL em particular, que já tiveram alguma exposição ao modelo relacional, 
mas que não sabem tanto sobre ele quanto deveriam, ou gostariam de saber. Este 
livro definitivamente não é para iniciantes; no entanto, ele também não é apenas um 
curso para refrescar sua memória. Para ser mais específico, estou certo de que você 
sabe algo sobre SQL; mas – e peço desculpas pelo tom possivelmente ofensivo aqui – 
se o seu conhecimento do modelo relacional deriva apenas de seu conhecimento de 
SQL, temo que você não conheça o modelo relacional tão bem como deveria e que 
provavelmente “saiba algo que não sabe”. Não tenho como enfatizar isso o suficiente: 
SQL e o modelo relacional não são iguais. Aqui, para ilustrar, estão algumas questões 
relacionais sobre as quais a SQL não é tão clara (para dizer o mínimo):
•	 O	que	são	realmente	bancos	de	dados,	relações	e	tuplas.
•	 A	diferença	entre	valores	de	relação	e	variáveis	de	relação.
•	 A	relevância	de	predicados	e	proposições.
•	 A	importância	de	nomes	de	atributos.
•	 A	função	crucial	de	restrições	de	integridade.
•	 O	princípio da informação e seu significado.
25Capítulo 1 ■ Preparando o cenário
E assim por diante (essa não é uma lista completa). Todas essas questões, e muitas 
outras, são abordadas neste livro.
Digo novamente: se o seu conhecimento do modelo relacional deriva apenas de 
seu conhecimento de SQL, então pode ser que você “saiba algo que não sabe”. Uma 
consequência é que você poderá perceber, lendo este livro, que terá de desaprender 
um pouco – e desaprender, infelizmente, é algo muito difícil.
Algumas observações sobre terminologia
Provavelmente você percebeu de imediato, na lista de itens de questões relacionais 
da seção anterior, que utilizei os termos formais relação, tuplas e atributo. A SQL não 
usa esses termos, é claro – ela utiliza, em vez disso, os termos mais “amigáveis” tabela, 
linha e coluna. E,antigo de S foi totalmente subs-
tituído por um novo valor. Evidentemente, o valor antigo (com cinco tuplas) e o novo 
(com quatro) são bastante semelhantes em certo sentido, mas eles definitivamente 
são valores distintos. Aliás, o DELETE que acabamos de mostrar é logicamente equi-
valente, e, na realidade, uma abreviação da atribuição relacional que vemos a seguir:
S := S MINUS ( S WHERE CITY = 'Athens' ) ; 
Assim como em todas as atribuições, o efeito aqui é que (a) a expressão de origem no 
lado direito é avaliada e, daí, (b) o valor que é o resultado dessa avaliação é, então, 
atribuído à variável-alvo no lado esquerdo, com o resultado geral já explicado.
Nota paralela: não posso demonstrar a afirmação precedente em SQL porque 
a SQL não suporta diretamente uma atribuição relacional. Em vez disso, de-
monstrei essa afirmação (assim como o DELETE original) em uma linguagem 
mais ou menos autoexplicativa chamada Tutorial D. Tutorial D é a linguagem 
SQL e Teoria Relacional50
que Hugh Darwen e eu usamos para ilustrar ideias relacionais em nosso livro 
Databases, Types, and the Relational Model: The Third Manifesto (veja o apêndice 
G) – e também vou usá-la no presente livro, quando estiver explicando conceitos 
relacionais15. Contudo, uma vez que meu público-alvo seja os praticantes de 
SQL, também vou, na maioria dos casos, mostrar os análogos em SQL. Nota: 
uma gramática BNF para a Tutorial D pode ser encontrada no apêndice D. 
Fim da nota paralela.
Para repetir, DELETE é a abreviação para uma determinada atribuição relacional – e, 
é claro, uma observação análoga se aplica também a INSERT e UPDATE: eles também 
são basicamente apenas abreviações para determinadas atribuições relacionais. Dessa 
forma, como mencionei na seção “Uma revisão do modelo original”, a atribuição rela-
cional é o operador de atualização fundamental no modelo relacional; de fato, ela é 
o único operador de atualização de que realmente precisamos, logicamente falando.
Assim, há uma diferença lógica entre valores de relação e variáveis de relação. O 
problema é que a literatura de bancos de dados tem historicamente usado o mesmo 
termo, relação, para significar ambos, e essa prática certamente levou à confusão16. 
Neste livro, portanto, vou distinguir muito cuidadosamente entre os dois daqui em 
diante – falarei em termos de valores de relação quando quiser dizer valores de rela-
ção, e em variáveis de relação quando quiser dizer variáveis de relação. No entanto, 
também vou, na maioria dos casos, abreviar valor de relação como apenas relação 
(exatamente como abreviamos, na maioria dos casos, valor inteiro como apenas inteiro). 
E vou abreviar variável de relação, na maioria dos casos, como relvar; por exemplo, 
direi que o banco de dados de fornecedores e peças contém três relvars (mais preci-
samente, três relvars de base).
Como um exercício, você pode se interessar por revisar o texto deste capítulo até 
aqui e verificar exatamente onde usei o termo relação quando na realidade deveria 
ter usado, em vez disso (ou também), o termo relvar.
Valores e variáveis
A diferença lógica entre relações e relvars é, na realidade, um caso especial de diferen-
ça lógica entre valores e variáveis em geral, e gostaria de dedicar alguns momentos 
15 Vários revisores reclamaram desse fato – isto é, sentiam que eu deveria utilizar a própria SQL, e 
não alguma linguagem não padronizada como a Tutorial D, para ilustrar ideias relacionais. (Um 
até sugeriu que o livro fosse renomeado “Tutorial D e teoria relacional”!) Mas a SQL como tal 
nunca foi pretendida como um veículo para ilustração de ideias relacionais, enquanto a Tutorial D 
explicitamente o foi; e, de qualquer modo, a SQL simplesmente não é adequada à tarefa. De fato, 
se ela o fosse, um livro como este não seria necessário, em primeiro lugar.
16 A SQL comete o mesmo erro, é claro, pois ela também tem apenas um termo, tabela, que deve ser 
entendido como, às vezes, significando um valor de tabela e, em outros casos, uma variável de tabela.
51Capítulo 1 ■ Preparando o cenário
para analisar o caso de forma geral. (Essa é uma leve digressão, mas penso que vale a 
pena dedicar o tempo aqui, pois um raciocínio claro nessa área pode ser – de muitas 
maneiras – de grande ajuda). Aqui estão, portanto, algumas definições:
Definição: um valor é o que os especialistas em lógica chamam de uma “cons-
tante individual”, como o inteiro 3. Um valor não tem localização no tempo e 
no espaço. Entretanto, valores podem ser representados na memória por meio 
de alguma codificação, e essas representações ou codificações realmente têm 
uma localização no tempo e no espaço. De fato, representações distintas do 
mesmo valor podem aparecer em um número variado de localizações distintas 
no tempo e no espaço – significando, livremente, que um número qualquer 
de variáveis distintas (veja a próxima definição) pode ter o mesmo valor, ao 
mesmo tempo ou em momentos distintos. Observe em particular que, por 
definição, um valor não pode ser atualizado; pois, se pudesse, então depois de 
tal atualização ele não seria mais esse valor.
Definição: uma variável é uma detentora de uma representação de um valor. 
Uma variável tem localização no tempo e no espaço. Além disso, variáveis, di-
ferentemente de valores, podem ser atualizadas; isto é, o valor atual da variável 
pode ser substituído por outro valor. (Afinal, é isso que “variável” significa – ser 
uma variável significa ser atualizável, e ser atualizável significa ser uma variável; 
de modo equivalente, ser uma variável significa ser atribuível, e ser atribuível 
significa ser uma variável.)
Por favor, observe com atenção que não são apenas elementos como o inteiro 3 que 
são valores legítimos. Pelo contrário, valores podem ser arbitrariamente complexos – 
por exemplo, um valor pode ser um ponto geométrico; ou um polígono; ou um raio 
X; ou um documento XML; ou uma impressão digital; ou um array; ou uma pilha; 
ou uma lista; ou uma relação (e assim por diante). Observações análogas também se 
aplicam às variáveis, é claro. Terei mais a dizer sobre tais assuntos no próximo capítulo.
Agora, você pode pensar que é difícil imaginar pessoas se confundindo com uma 
distinção tão óbvia e fundamental como a que existe entre valores e variáveis. Na 
realidade, no entanto, é bastante fácil cair em armadilhas nessa área. Como uma 
forma de ilustração, considere o trecho a seguir, retirado de um tutorial sobre bancos 
de dados de objetos (as porções em itálico dentro das chaves são comentários feitos 
por mim mesmo):
Distinguimos o tipo declarado de uma variável... do tipo do objeto que é o 
valor atual da variável [então um objeto é um valor]... Distinguimos objetos 
de valores [então um objeto não é um valor afinal de contas]... Um modifi-
cador [é um operador de tal modo que é] possível observar seu efeito em 
algum objeto [então, na realidade, um objeto é uma variável].
SQL e Teoria Relacional52
Observações de encerramento
Isso nos traz ao final deste capítulo preliminar. Na maior parte, meu objetivo tem sido 
apenas lhe dizer o que espero que você já saiba (e você pode, portanto, ter sentido 
que o capítulo foi um pouco leve em substância técnica). De qualquer forma, apenas 
para revisar brevemente:
•	 Expliquei	porque	estaríamos	preocupados	com	princípios,	e	não	produtos,	e	
porque vou usar a terminologia formal, como relação, tupla e atributo (pelo menos 
em contextos relacionais) – em vez de suas contrapartes SQL mais amigáveis.
•	 Ofereci	uma	visão	geral	do	modelo	original,	abordando,	em	particular,	estes	
conceitos: tipo (ou domínio), relação de grau n, tuplas, atributo, chave candidata 
(chave, para abreviar), chave primária, chave estrangeira, integridade de entida-
de, integridade referencial, atribuição relacional e a álgebra relacional. (Também 
mencionei brevemente o cálculo relacional.) Com respeito à álgebra, mencionei 
a propriedade de fechamento e descrevi muito brevemente os operadores de 
restrição, projeção, produto,intersecção, união, diferença e junção.
•	 Discuti	várias	propriedades	das	relações,	apresentando	os	termos	cabeçalho, 
corpo, cardinalidade e grau. Relações não têm tuplas duplicadas, nenhuma 
ordenação de tuplas de cima para baixo e nenhuma ordenação de atributos 
da esquerda para a direita. Também discuti as diferenças entre relações de base 
(ou relvars de base, na realidade) e visões. E expliquei que todo subconjunto de 
uma tupla é uma tupla, todo subconjunto de um cabeçalho é um cabeçalho e 
todo subconjunto de um corpo é um corpo.
•	 Discuti	as	diferenças	lógicas	entre	modelo e implementação, valores e variáveis em 
geral, e relações e relvars em particular. A discussão de modelo versus implementação, 
em particular, levou-nos a uma discussão sobre independência de dados físicos.
•	 Afirmei	que	a	SQL	e	o	modelo	relacional	não	representam	o	mesmo	conceito.	
Já vimos algumas diferenças – por exemplo, o fato de que a SQL permite linhas 
duplicadas, de que tabelas SQL têm uma ordenação de colunas da esquerda 
para a direita e de que a SQL não distingue entre valores de tabela e variáveis 
de tabela – e veremos muitas outras nas páginas seguintes.
Um último ponto (não mencionei isso explicitamente antes, mas espero que esteja 
claro a partir de tudo que disse): em geral, o modelo relacional é declarativo, e não 
procedural, por natureza; ou seja, ele sempre favorece soluções declarativas em vez 
de soluções procedurais, sempre que tais soluções sejam viáveis. A razão é óbvia: 
declarativo significa que o sistema faz o trabalho, procedural significa que o usuário 
faz o trabalho (então, estamos falando sobre produtividade, dentre outros conceitos). 
É por isso que o modelo relacional suporta consultas declarativas, atualizações 
53Capítulo 1 ■ Preparando o cenário
declarativas, definições de visão declarativas, restrições de integridade declarativas 
e assim por diante.
Nota: depois de ter escrito o parágrafo anterior pela primeira vez, fui informado de que 
pelo menos um produto SQL bem conhecido aparentemente utiliza o termo “declarativo” 
para significar que o sistema não faz o trabalho! Isto é, ele permite que o usuário faça 
certas afirmações declarativamente (por exemplo, o fato de uma determinada visão ter 
uma determinada chave), mas não obriga a restrição indicada por essa declaração – ele 
simplesmente presume que o usuário irá obrigá-la. Tais abusos terminológicos fazem 
pouco para ajudar a causa do entendimento genuíno. Caveat lector.
Exercícios
1.1 (Retirado do corpo do capítulo, mas levemente reescrito aqui.) Se você ainda não o 
fez, verifique o capítulo novamente e identifique todos os locais em que usei o termo 
relação e deveria, por direito, ter usado o termo relvar, em vez disso.
1.2 Quem foi E. F. Codd?
1.3 O que é um domínio?
1.4 O que você entende pelo termo integridade referencial?
1.5 Os termos cabeçalho, corpo, atributo, tupla, cardinalidade e grau, definidos no corpo 
do capítulo para valores de relação, podem ser todos interpretados da forma óbvia 
para se aplicar também a relvars. Procure entender essa observação.
1.6 Faça a distinção entre os dois significados do termo modelo de dados.
1.7 Explique, com suas próprias palavras, (a) independência de dados físicos e (b) 
a diferença entre modelo e implementação.
1.8 No corpo do capítulo, eu disse que tabelas como aquelas das figuras 1.1 e 1.3 não 
eram relações como tais, mas, em vez disso, imagens de relações. Quais são alguns dos 
pontos de diferença específicos entre essas imagens e as relações correspondentes?
1.9 (Tente este exercício sem revisar o corpo do capítulo.) Quais relvars o banco de dados 
de fornecedores e peças contém? Que atributos elas envolvem? Que chaves e chaves 
estrangeiras elas têm? (O sentido deste exercício é que vale a pena se tornar o mais 
familiarizado possível com a estrutura, pelo menos em termos gerais, do exemplo 
corrente. Não é tão importante lembrar-se detalhadamente dos valores dos dados 
em si – ainda que não seja má ideia lembrar-se deles.)
1.10 “Existe apenas um modelo relacional.” Explique essa afirmação.
1.11 A seguir, temos um trecho retirado de certo livro teórico de bancos de dados: “É 
importante fazer uma distinção entre relações armazenadas, que são tabelas, e relações 
SQL e Teoria Relacional54
virtuais, que são visões... Utilizaremos relação apenas onde uma tabela ou visão puder 
ser utilizada. Quando quisermos enfatizar que uma relação está armazenada, em vez 
de uma visão, vamos, às vezes, utilizar o termo relação de base ou tabela de base.” Esse 
texto revela várias confusões e equívocos com relação ao modelo relacional. Identi-
fique tantos quantos você puder.
1.12 A seguir, temos um trecho retirado de outro livro teórico de bancos de dados: 
“O modelo relacional (...) define tabelas simples para cada relação e relacionamentos 
muitos-para-muitos. Chaves de referência cruzada ligam as tabelas, representando os 
relacionamentos entre as entidades. Índices primários e secundários fornecem acesso 
rápido aos dados com base em qualificações.” Pretende-se que esse texto seja uma 
definição (!) do modelo relacional... O que há de errado nele?
1.13 Escreva instruções CREATE TABLE para uma versão SQL do banco de dados 
de fornecedores e peças.
1.14 A seguir temos uma típica instrução SQL INSERT no banco de dados de for-
necedores e peças:
INSERT INTO SP ( SNO , PNO , QTY ) VALUES ( 'S5' , 'P6' , 250 ) ;
Mostre uma operação de atribuição relacional equivalente. Nota: reconheço que 
ainda não expliquei a sintaxe da atribuição relacional detalhadamente, por isso não 
se preocupe tanto em fornecer uma resposta sintaticamente correta – apenas faça o 
melhor que puder.
1.15 (Mais difícil.) A seguir temos uma típica instrução SQL UPDATE no banco de 
dados de fornecedores e peças:
UPDATE S SET STATUS = 25 WHERE CITY = 'Paris' ;
Mostre uma operação de atribuição relacional equivalente. (O propósito deste exer-
cício é fazer você pensar sobre o que está envolvido. Ainda não lhe disse o suficiente 
neste capítulo para permitir que você o responda completamente. Veja as discussões 
sobre consultas “e se” no capítulo 7 para uma explicação detalhada.)
1.16 Ao longo do capítulo, eu disse que a SQL não suporta diretamente a atribuição 
relacional. Ele a suporta indiretamente? Se afirmativo, de que forma? Uma questão re-
lacionada: podem todas as atribuições relacionais ser expressas em termos de INSERT 
e/ou DELETE e/ou UPDATE? Se negativo, por que não? Quais são as implicações?
1.17 De um ponto de vista prático, por que você acha que tuplas duplicadas, ordena-
ção de tuplas de cima para baixo e ordenação de atributos da esquerda para a direita 
são todas ideias muito ruins? (Essas questões deliberadamente não foram respondidas 
ao longo do capítulo, e este exercício pode servir melhor como uma base para dis-
cussões em grupo. Analisaremos mais de perto tais questões futuramente no livro.)em geral, sou simpático à ideia de usar termos mais amigáveis, se 
eles podem ajudar a tornar as ideias mais palatáveis. No caso presente, entretanto, 
parece-me que, infelizmente, eles não tornam as ideias mais palatáveis; em vez disso, 
eles as distorcem e, na realidade, prestam um grande desserviço à causa do entendi-
mento genuíno. A verdade é que uma relação não é uma tabela, uma tupla não é uma 
linha e um atributo não é uma coluna. E ainda que possa ser aceitável fingirmos o 
contrário em contextos informais – de fato, eu mesmo muitas vezes faço isso –, diria 
que isso é aceitável apenas se todos entenderem que os termos mais amigáveis ao 
usuário são apenas uma aproximação da verdade e que falham, no sentido geral, em 
capturar a essência do que está realmente acontecendo. Colocando de outra forma: 
se você entende a situação real, então o uso criterioso de termos amigáveis pode ser 
uma boa ideia; mas para aprender e apreciar a situação real, em primeiro lugar, você 
realmente precisa entender os termos formais. Neste livro, portanto, tenderei a usar 
esses termos formais (pelo menos quando estiver falando sobre o modelo relacional, 
em vez de SQL) e darei definições precisas para eles no momento relevante. Em con-
textos SQL, por contraste, usarei os termos da própria SQL. 
E outro ponto sobre terminologia. Tendo dito que a SQL tenta simplificar um con-
junto de termos, devo também dizer que ela faz tudo que pode para complicar outros. 
Refiro-me ao seu uso dos termos operador, função, procedimento, rotina e método – todos 
os quais denotam essencialmente o mesmo elemento (com, talvez, diferenças muito 
pequenas). Neste livro, utilizarei o termo operador em todo o texto; portanto, vou me 
referir, por exemplo, a “=” (comparação de igualdade), “:=” (atribuição), “+” (adição), 
DISTINCT, JOIN, SUM, GROUP BY (etc., etc.), todos especificamente como operadores.
Falando sobre SQL, incidentalmente, deixe-me lembrá-lo de que (como foi dito no 
prefácio) uso esse termo para representar exclusivamente a versão padrão da lingua-
gem, exceto em alguns locais em que o contexto exige o contrário2. Entretanto:
2 O padrão tem passado por várias versões, ou edições, ao longo dos anos. A versão atual quando 
da redação deste texto é SQL:2008 (para a qual uma referência formal pode ser encontrada no 
SQL e Teoria Relacional26
•	 O	uso	padronizado	da	terminologia	às	vezes	não	é	muito	adequado.	Em	tais	
situações, geralmente prefiro utilizar minha própria terminologia. Por exemplo, 
uso o termo expressão de tabela em vez do termo padrão expressão de consulta 
por estes motivos, dentre outros: primeiro, o valor que tais expressões denotam 
é realmente uma tabela e não uma consulta; segundo, consultas, de qualquer 
forma, não são o único contexto em que tais expressões são utilizadas. (Na 
realidade, o padrão de fato utiliza o termo expressão de tabela, mas, uma vez 
mais, ele o faz de modo inapropriado; para ser específico, ele o utiliza para se 
referir ao que vem depois da cláusula SELECT em uma expressão SELECT.)
•	 Dando	continuidade	ao	ponto	anterior,	devo	acrescentar	que	nem	todas	as	
expressões de tabela – seja em meu sentido ou no sentido padronizado – são 
válidas em SQL em todos os contextos em que poderíamos esperar que elas o 
fossem. Em particular, uma invocação JOIN específica, ainda que certamente 
denote uma tabela, não pode aparecer como uma expressão de tabela “inde-
pendente” (isto é, no nível mais externo de aninhamento), nem pode aparecer 
como a expressão de tabela entre parênteses que constitui uma subconsulta 
(veja o capítulo 12)3. Por favor, note que essas afirmações se aplicam a muitas das 
discussões individuais do corpo do livro; no entanto, seria muito tedioso as seguir 
repetindo, e eu não o farei. (Entretanto, elas são refletidas na gramática BNF no 
capítulo 12.)
•	 Neste	livro,	ignoro	aspectos	do	padrão	que	poderiam	ser	considerados	como	
esoterismo barato – especialmente se não fizerem parte do que o padrão chama 
de “Core SQL” ou se não tiverem muita relação com processamento relacional 
como tal. Exemplos aqui incluem as funções chamadas analíticas ou de janela 
(OLAP); SQL dinâmico; tabelas temporárias; e detalhes de tipos definidos 
pelo usuário.
•	 Por	motivos	que	não	são	importantes	aqui,	utilizo	um	estilo	para	comentários	
que difere daquele do padrão. Para ser específico, mostro comentários como 
strings de texto em itálico, entre delimitadores “/*” e “*/”.
Esteja ciente, no entanto, de que todos os produtos SQL incluem funcionalidades que 
não são parte do padrão em si. IDs de linhas fornecem um exemplo comum. Meu 
conselho geral a respeito de tais funcionalidades é: utilize-as, se desejar – mas não se 
elas violarem princípios relacionais (afinal, estou defendendo o que deveria ser uma 
abordagem relacional à SQL). Por exemplo, IDs de linha, em particular, provavelmente 
violam o Princípio da intercambialidade (veja o capítulo 9), o Princípio da informação 
apêndice G); a versão anterior era SQL:2003, antes dessa, SQL:1999; e a anterior a essa, SQL:1992. 
A maioria das funcionalidades SQL discutidas neste livro estava presente na SQL:1992, e muitas 
vezes até em versões anteriores.
3 Essas limitações particulares foram adicionadas no padrão SQL:2003; elas não se aplicavam ao 
SQL:1992, que é onde invocações JOIN explícitas foram primeiro apresentadas, nem ao SQL:1999.
27Capítulo 1 ■ Preparando o cenário
(veja o apêndice A) ou ambos; e se o fizerem, então eu certamente não os utilizaria. 
No entanto, aqui e em todos os locais, a regra suprema é: você pode fazer o que quiser, 
desde que saiba o que está fazendo.
Princípios, não produtos
Vale parar por um momento para analisar a questão de por que, como eu disse antes, 
você, como um profissional de bancos de dados, precisa conhecer o modelo relacional. 
O motivo é que o modelo relacional não é específico a produtos; em vez disso, ele 
se preocupa com princípios. O que quero dizer com princípios? Bem, aqui está uma 
definição (do Chambers Twentieth Century Dictionary):
princípio: uma fonte, raiz, origem: aquilo que é fundamental: essencial 
em natureza: base teórica: uma verdade fundamental a qual outras têm 
por base ou da qual se originam.
O ponto sobre princípios é: eles perduram. Por contraste, produtos e tecnologias (e 
a linguagem SQL, nesse sentido) mudam o tempo todo – mas princípios não. Por 
exemplo, vamos supor que você conheça Oracle; aliás, suponha que você seja um 
especialista em Oracle. Mas se Oracle é tudo que você conhece, então seu conheci-
mento não é necessariamente transferível para, digamos, um ambiente DB2 ou SQL 
Server (ele pode até dificultar o progresso nesse novo ambiente). Contudo, se você 
conhece os princípios subjacentes – em outras palavras, se você conhece o modelo 
relacional –, você tem conhecimentos e habilidades que serão transferíveis: conheci-
mentos e habilidades que você poderá aplicar em todos os ambientes e que nunca 
serão obsoletos.
Neste livro, portanto, estaremos preocupados com princípios, não produtos, e fun-
damentos, não tendências ou modismos. Porém eu realmente percebo que, às vezes, 
você tem de fazer compromissos e concessões no mundo real. Como um exemplo, às 
vezes você pode ter boas razões pragmáticas para não projetar o banco de dados de 
modo teoricamente ótimo. Como outro exemplo, considere a SQL novamente. Ainda 
que certamente seja possível utilizar SQL relacionalmente (na maioria dos casos, de 
qualquer modo), às vezes você perceberá – porque implementações existentes estão 
longe de serem perfeitas – que existem severas penalidades de desempenho em fazê-
-lo... caso em que você pode ser mais ou menos forçado a fazer algo não “verdadei-
ramente relacional” (como escrever uma consulta de modo não natural para obrigar 
a implementação a usar um índice). No entanto, acredito firmemente que você deva 
sempre assumir esses compromissos e concessões a partir de uma posição de força 
conceitual. Ou seja:
•	 Você	deve	compreender	o	queestá	fazendo	quando	decide	assumir	tal	com-
promisso.
SQL e Teoria Relacional28
•	 Você	deve	saber	qual	é	a	situação	teoricamente	correta	e	deve	ter	fortes	motivos	
para se afastar dela.
•	 Você	também	deve	documentar	esses	motivos,	para	que,	caso	eles	deixem	de	
ser válidos em algum momento futuro (por exemplo, em razão de um novo 
lançamento do produto utilizado fazer um trabalho melhor em algum sentido), 
possa ser possível abandonar o compromisso original.
A citação a seguir – que é atribuída a Leonardo da Vinci (1452-1519) e tem, portanto, 
aproximadamente 500 anos de idade – resume a situação admiravelmente:
Aqueles que se enamoram da prática sem a teoria são como um navegador 
que entra em um navio sem leme nem bússola, que jamais tem certeza 
para onde vai. Sempre a prática deve ser edificada sobre um conhecimento 
sólido de teoria.
(Está bem, o itálico fui eu que acrescentei.)
Uma revisão do modelo original
O propósito desta seção é servir como um pontapé inicial para discussões subse-
quentes; ela revisa alguns dos aspectos mais básicos do modelo relacional como 
originalmente definido. Note esse qualificador – “como originalmente definido”! 
Um dos equívocos mais difundidos sobre o modelo relacional é o de que ele é algo 
totalmente estático. Ele não é. Ele é, nesse sentido, como a matemática: a matemática 
também não é algo estático, mas muda ao longo do tempo. Na realidade, o modelo 
relacional pode, ele mesmo, ser visto como um pequeno ramo da matemática; como 
tal, ele evolui ao longo do tempo, à medida que novos teoremas são provados e novos 
resultados são descobertos. Além disso, essas novas contribuições podem ser feitas 
por qualquer pessoa que seja competente para fazê-lo; assim como outros ramos da 
matemática, o modelo relacional, ainda que tenha sido originalmente inventado por 
um homem, tornou-se um esforço comunitário e agora pertence ao mundo.
Por falar nisso, caso você não saiba, esse homem foi E. F. Codd, na época, pesquisa-
dor da IBM (E de Edgar e F de Frank – mas ele sempre assinava com suas iniciais; 
para seus amigos, entre os quais tenho orgulho em me incluir, ele era Ted). Foi no 
final de 1968 que Codd, um matemático por treinamento, primeiro percebeu que a 
disciplina da matemática poderia ser utilizada para injetar princípios sólidos em um 
campo, o gerenciamento de bancos de dados, que antes era bastante deficiente em tais 
qualidades. Sua definição original do modelo relacional apareceu em um relatório de 
pesquisa da IBM em 1969; falarei mais sobre esse texto no apêndice G.
29Capítulo 1 ■ Preparando o cenário
Características estruturais
O modelo original tinha três componentes principais – estrutura, integridade e 
manipulação; descreverei brevemente um de cada vez. Por favor, note de imediato, 
no entanto, que todas as “definições” que darei são bastante genéricas; eu as tornarei 
mais precisas à medida que e quando for apropriado em capítulos futuros.
Em primeiro lugar, então, estrutura. A principal característica estrutural é, evidente-
mente, a relação em si, e como todos sabem é comum desenharmos tais relações no 
papel como tabelas (veja a figura 1.1 para um exemplo autoexplicativo). Relações são 
definidas por tipos (também conhecidos como domínios); um tipo é basicamente um 
acervo conceitual de valores a partir dos quais atributos efetivos, em relações efetivas, 
assumem seus valores efetivos. Com referência, por exemplo, ao simples banco de 
dados de departamentos (departments) e funcionários (employees) da figura 1.1 pode 
haver um tipo chamado DNO (“números de departamentos”), que é o conjunto de 
todos os números de departamentos válidos, e daí o atributo chamado DNO na 
relação DEPT e o atributo chamado DNO na relação EMP conteriam valores desse 
acervo conceitual. (Por falar nisso, não é necessário – ainda que, muitas vezes, seja 
uma boa ideia – que atributos tenham o mesmo nome do tipo correspondente, e, 
frequentemente, eles não o terão. Veremos muitos contraexemplos futuramente.)
Figura 1.1 – Valores de exemplo do banco de dados de departamentos e funcionários.
Como disse, tabelas como aquela da figura 1.1 representam relações: relações de grau 
n, para sermos precisos. Uma relação de grau n pode ser imaginada como uma tabela 
com n colunas; as colunas nessa figura representam atributos da relação e as linhas 
representam tuplas. O valor n pode ser qualquer inteiro não negativo. Uma relação de 
grau 1 é dita como sendo unária; uma relação de grau 2 é dita binária; uma relação 
de grau 3, ternária; e assim por diante.
O modelo relacional também suporta vários tipos de chaves. Para começar – e esse 
ponto é crucial! –, toda relação tem pelo menos uma chave candidata4. Uma chave 
candidata é apenas um identificador exclusivo; em outras palavras, ela é uma combi-
nação de atributos – muitas vezes, mas nem sempre, uma “combinação” consistindo 
4 Estritamente falando, essa frase deveria dizer “Cada relvar tem pelo menos uma chave candidata” (veja 
a seção “Relações versus relvars”, mais adiante). Nota: na realidade, uma afirmação similar também 
se aplica em outro ponto deste capítulo. O exercício 1.1 ao final do capítulo trata dessa questão.
SQL e Teoria Relacional30
de apenas um único atributo –, de tal modo que toda tupla na relação tenha um valor 
exclusivo para a combinação em questão. Na figura 1.1, por exemplo, todo departamen-
to tem um número de departamento exclusivo e todo funcionário tem um número 
de funcionário exclusivo, de modo que podemos dizer que {DNO} é uma chave 
candidata para DEPT e {ENO} é uma chave candidata para EMP. A propósito, repare 
nos caracteres de chaves de abertura e de fechamento; repetindo: chaves candidatas 
são sempre combinações, ou conjuntos, de atributos (mesmo quando o conjunto em 
questão contém apenas um atributo), e a representação convencional de um conjunto 
no papel é uma lista de elementos, separados por vírgulas, entre caracteres de chaves.
Nota paralela: essa é a primeira vez que mencionei a expressão lista separada 
por vírgulas, mas vou utilizá-la bastante em páginas futuras. Ela pode ser 
definida desta forma: deixe que xyz seja algum construto 5 sintático (por 
exemplo, “nome de atributo”). Então a expressão lista separada por vírgulas 
xyz denota uma sequência de zero ou mais xyzs na qual cada par de xyzs 
adjacentes é separado por uma vírgula (assim como, opcionalmente, por 
um ou mais espaços antes ou depois da vírgula, ou em ambas as posições). 
Por exemplo, se A, B e C forem nomes de atributos, então todos os exem-
plos a seguir serão listas separadas por vírgulas de nomes de atributos:
A , B , C
C , A , B
B
A , C
Assim também é a sequência vazia de nomes de atributos.
Além disso, quando alguma lista separada por vírgulas é colocada entre 
caracteres de chaves e, portanto, denota um conjunto, então (a) a ordem 
em que os elementos são mostrados dentro dessa lista é imaterial (pois 
conjuntos não têm ordenamento para seus elementos), e (b) se um elemento 
aparece mais de uma vez, ele é tratado como se aparecesse apenas uma vez 
(pois conjuntos não contêm elementos duplicados). Fim da nota paralela.
Continuando, uma chave primária é uma chave candidata que foi selecionada para 
tratamento especial de alguma forma. Se a relação em questão tem apenas uma cha-
ve candidata, não faz nenhuma diferença real se decidirmos chamar essa chave de 
“primária”. No entanto, se essa relação tem duas ou mais chaves candidatas, então é 
habitual escolher uma delas como primária, significando que ela é, de alguma for-
ma, “mais igual do que as outras”. Vamos supor, por exemplo, que todo funcionário 
5 N.T.: Construto é um elemento não tangível, criado para realizar uma determinada função (a rigor, 
tudo em programação são construtos, já que nenhum deles existe fisicamente). 
31Capítulo 1 ■ Preparando o cenário
sempre tenha tanto uma chave exclusiva de funcionário quanto um nome exclusivo 
de funcionário – esse talvez não seja um exemplo muito realista, mas é bom osufi-
ciente para os propósitos atuais – de modo que {ENO} e {ENAME} sejam ambas 
chaves candidatas para EMP. Então poderíamos escolher {ENO}, por exemplo, para 
ser a chave primária.
Observe que eu disse que é habitual escolher uma chave primária. De fato, é habitual 
– mas não é 100% necessário. Se houver apenas uma chave candidata, então haverá 
pouca escolha e nenhum problema; mas se houver duas ou mais, então ter de esco-
lher uma e torná-la primária pode soar um tanto quanto arbitrário (pelo menos para 
mim). Certamente, há situações em que não parece haver nenhum bom motivo para 
fazermos tal escolha. Neste livro, portanto, vou geralmente seguir a disciplina da chave 
primária – e, em figuras como a figura 1.1, vou indicar atributos de chave primária com 
um sublinhado duplo6 –, mas desejo reforçar o fato de que são realmente as chaves 
candidatas, e não as chaves primárias, que são significativas a partir de um ponto 
de vista relacional. Parcialmente por esse motivo, deste ponto em diante vou utilizar 
o termo chave, sem qualificação, para significar qualquer chave candidata, indepen-
dentemente de a chave candidata em questão ter sido designada como “primária”. 
(Caso você esteja se perguntado, o “tratamento especial” dado às chaves primárias 
com relação às chaves candidatas é, de qualquer modo, principalmente sintático em 
natureza; ele não é fundamental e não é muito importante.)
Por fim, uma chave estrangeira (foreign key) é uma combinação, ou conjunto, de atri-
butos FK em alguma relação r2 de modo que cada valor de FK tenha de ser igual a 
algum valor de alguma chave K em alguma relação r1 (r1 e r2 não são necessariamente 
distintas)7. Com referência à figura 1.1, por exemplo, {DNO} é uma chave estrangeira 
em EMP cujos valores devem corresponder a valores da chave {DNO} em DEPT 
(como tentei sugerir por meio de uma seta identificada adequadamente na figura). 
Aqui, por devem corresponder eu quero dizer que se, por exemplo, EMP contiver uma 
tupla na qual o atributo DNO tenha o valor D2, então DEPT também deve conter uma 
tupla na qual o atributo DNO tenha o valor D2 – pois, do contrário, EMP mostraria 
algum funcionário como se estivesse em um departamento inexistente, e o banco de 
dados não seria um “modelo fiel da realidade”.
Características de integridade
Uma restrição de integridade (restrição, para abreviar) é, basicamente, apenas uma 
expressão booleana que deve ser avaliada como TRUE. No caso de departamentos 
e funcionários, por exemplo, podemos ter uma restrição de forma que valores de 
6 Veja o exercício 5.27 no capítulo 5 para obter mais explicações sobre essa convenção.
7 Essa definição é deliberadamente um tanto quanto simplificada. Uma definição melhor pode ser 
encontrada no capítulo 5.
SQL e Teoria Relacional32
SALARY (salário) devam ser maiores do que zero. Agora, qualquer banco de dados 
estará sujeito a inúmeras restrições; no entanto, todas essas restrições serão necessa-
riamente específicas ao banco de dados e serão, portanto, expressas em termos das 
relações desse banco de dados. Por contraste, o modelo relacional como originalmente 
formulado inclui duas restrições genéricas – genéricas, no sentido de que se aplicam a 
qualquer banco de dados, livremente falando. Uma tem relação com chaves primárias 
e outra, com chaves estrangeiras. Aqui estão elas:
•	 A regra de integridade de entidade: atributos de chave primária não permitem 
nulos.
•	 A regra de integridade referencial: não deve haver nenhum valor de chave estran-
geira não correspondido.
Vou explicar a segunda regra, primeiro. Por valor de chave estrangeira não correspondido 
quero dizer um valor de chave estrangeira para o qual não exista um valor igual ao da 
chave candidata pertinente (a “chave-alvo”); assim, por exemplo, o banco de dados de 
departamentos para funcionários estaria em violação da regra de integridade referen-
cial se incluísse, digamos, uma tupla EMP com um valor DNO de D2, mas nenhuma 
tupla DEPT com esse mesmo valor DNO. Assim, a regra de integridade referencial 
simplesmente explicita a semântica das chaves estrangeiras; o nome “integridade 
referencial” deriva do fato de que um valor de chave estrangeira pode ser considerado 
uma referência à tupla com esse mesmo valor para a chave-alvo correspondente. Na 
prática, portanto, a regra simplesmente diz: se B referencia A, então A deve existir.
Quanto à regra de integridade de entidade, bem, aqui tenho um problema. O fato 
é que rejeito o conceito de “nulos” inteiramente; ou seja, tenho a forte opinião de 
que nulos não têm lugar no modelo relacional. (Codd, obviamente, pensava diferente, 
mas tenho razões significativas para assumir essa posição.) Para explicar a regra de 
integridade de entidade, portanto, preciso, nesse caso, suspender minha descrença 
(pelo menos por alguns momentos). O que começarei a fazer agora... Mas, por favor, 
entenda que voltarei a toda essa questão dos nulos nos capítulos 3 e 4.
Em essência, então, um nulo é um “marcador” que significa valor desconhecido. Cru-
cialmente, ele não é, em si, um valor; ele é, para repetir, um marcador, ou sinalizador. 
Por exemplo, vamos supor que não conheçamos o salário do funcionário E2. Então, 
em vez de inserir algum valor de SALARY real na tupla para o empregado E2 em rela-
ção a EMP – não podemos inserir um valor real, por definição, precisamente porque 
não sabemos qual deve ser esse valor – marcamos a posição do SALARY dentro dessa 
tupla como um nulo, como indicado aqui:
33Capítulo 1 ■ Preparando o cenário
Agora, é importante entender que essa tupla não contém nada na posição SALARY. 
Porém é muito difícil fazer uma imagem do nada! Tentei mostrar que a posição SALARY 
está vazia, na figura anterior, usando um sombreado, mas seria mais correto não mostrar 
nada nessa posição. Seja como for, utilizarei essa mesma convenção de representação 
de posições vazias com sombreado em outros locais deste livro – mas esse sombreado, 
repito, não representa nenhum tipo de valor. Você pode pensar nisso (o sombreado, 
quer dizer) como constituindo o “marcador” – ou sinalizador de nulo, se preferir.
Retornando à regra de integridade de entidade: em termos da relação EMP, então, 
essa regra diz, de maneira solta, que a tupla de determinado funcionário pode ter um 
nome desconhecido, ou um número de departamento desconhecido, ou um salário 
desconhecido – mas ela não pode ter um número de funcionário desconhecido. A jus-
tificativa para essa situação é que, se o número de funcionário fosse desconhecido, nem 
sequer saberíamos de qual “entidade” (isto é, qual funcionário) estaríamos falando.
Isso é tudo que desejo dizer sobre nulos por enquanto. Por favor, esqueça-se deles 
até segunda ordem.
Características manipulativas
A parte manipulativa do modelo, por sua vez, se divide em duas:
•	 A	álgebra relacional, que é uma coleção de operadores (por exemplo, de diferença, 
ou MINUS) que podem ser aplicados à relação.
•	 Um	operador	de	atribuição relacional, que permite que o valor de alguma ex-
pressão relacional (por exemplo, r1 MINUS r2, onde r1 e r2 são relações) seja 
atribuído a alguma relação.
O operador de atribuição relacional é, fundamentalmente, a forma como atualizações 
são feitas no modelo relacional; terei mais a dizer sobre ele futuramente, na seção 
“Relações versus Relvars”. Nota: sigo a convenção habitual ao longo deste livro ao uti-
lizar o termo genérico atualização para me referir aos operadores INSERT, DELETE e 
UPDATE (e de atribuição) considerados coletivamente. Quando quiser me referir ao 
operador UPDATE especificamente, vou utilizá-lo todo em letras maiúsculas, como 
acabamos de ver.
Quanto à álgebra relacional, ela consiste em um conjunto de operadores que – falando 
bastante livremente – permitem-nos derivar “novas” relações de relações “antigas”. 
Cada operador desse tipo toma uma ou mais relações como entrada e produz outra 
relação como saída; por exemplo, a diferença (MINUS) toma duas relações como 
entrada e “subtrai” umada outra, para derivar outra relação como saída. E é muito 
importante que a saída seja outra relação: essa é a bem conhecida propriedade de 
fechamento da álgebra relacional. A propriedade de fechamento é o que nos permite 
SQL e Teoria Relacional34
escrever expressões relacionais aninhadas; já que a saída de cada operação é do 
mesmo tipo da entrada, a saída de uma operação pode se tornar a entrada de outra. 
Por exemplo, podemos tomar a diferença r1 MINUS r2, alimentar o resultado como 
entrada de uma união com alguma relação r3, alimentar esse resultado para uma 
intersecção com alguma relação r4, e assim por diante.
Agora, um número qualquer de operadores pode ser definido que se encaixe na 
simples definição de que “uma ou mais relações entram, exatamente uma relação 
sai”. Aqui, descrevo brevemente quais costumam ser imaginados como os operadores 
originais (essencialmente, aqueles que Codd definiu em seus textos iniciais)8; darei 
mais detalhes no capítulo 6 e, no capítulo 7, também descreverei vários operadores 
adicionais. A figura 1.2 é uma representação pictórica desses operadores originais.
Figura 1.2 – Álgebra relacional original.
Nota: se você não está familiarizado com esses operadores e considera as descrições 
um pouco difíceis de acompanhar, não se preocupe com isso; como já disse, vou falar 
sobre isso muito mais detalhadamente, com vários exemplos, em capítulo futuros.
8 Exceto que Codd definiu também um operador chamado de divisão. Vou explicar no capítulo 7 
porque omito esse operador aqui.
35Capítulo 1 ■ Preparando o cenário
Restrição
Retorna uma relação contendo todas as tuplas de uma relação específica que 
satisfaçam a uma condição especificada. Por exemplo, podemos restringir a 
relação EMP a apenas aquelas tuplas cujo valor DNO seja D2.
Projeção
Retorna uma relação contendo todas as (sub)tuplas que permaneçam em uma 
relação especificada depois que atributos especificados foram removidos. Por 
exemplo, podemos projetar a relação EMP em apenas os atributos ENO e 
SALARY (removendo, dessa forma, os atributos ENAME e DNO).
Produto
Retorna uma relação contendo todas as possíveis tuplas que sejam uma com-
binação de duas tuplas, uma de cada duas relações especificadas. Nota: esse 
operador também é conhecido variavelmente como produto cartesiano (às vezes, 
produto cartesiano estendido ou expandido), produto cruzado, junção cruzada e 
junção cartesiana; aliás, ele é apenas um caso especial de junção, como veremos 
no capítulo 6.
Intersecção
Retorna uma relação contendo todas as tuplas que apareçam em ambas as rela-
ções especificadas. (Na realidade, a intersecção, tal como o produto, é também 
um caso especial de junção, como veremos no capítulo 6.)
União
Retorna uma relação contendo todas as tuplas que apareçam em qualquer uma 
das duas, ou em ambas as relações especificadas.
Diferença
Retorna uma relação contendo todas as tuplas que apareçam na primeira, mas 
não na segunda das duas relações especificadas.
Junção
Retorna uma relação contendo todas as tuplas possíveis que sejam uma com-
binação de duas tuplas, uma de cada duas relações especificadas, de modo que 
as duas tuplas que contribuam para qualquer tupla de resultado tenham um 
valor comum para os atributos comuns das duas relações (e esse valor comum 
aparece apenas uma vez, e não duas, nessa tupla de resultado). Nota: esse tipo 
de junção era originalmente chamado de junção natural, para distingui-lo dos 
vários outros tipos que serão discutidos futuramente neste livro. Como, no 
SQL e Teoria Relacional36
entanto, uma junção natural está longe de ser o tipo mais importante, tornou-
-se prática padrão tomar-se o termo não qualificado junção como significando 
a junção natural especificamente; seguirei essa prática neste livro.
Um último ponto antes de fecharmos esta subseção: como você provavelmente sabe, 
existe também algo chamado cálculo relacional. O cálculo relacional pode ser con-
siderado uma alternativa à álgebra relacional; ou seja, em vez de dizer que a parte 
manipulativa do modelo relacional consiste na álgebra relacional (mais a atribuição 
relacional), podemos igualmente dizer que ela consiste no cálculo relacional (mais 
a atribuição relacional). Os dois são equivalentes e intercambiáveis, no sentido de 
que para cada expressão algébrica existe uma expressão logicamente equivalente 
no cálculo e vice-versa. Falarei mais sobre cálculo futuramente, principalmente nos 
capítulos 10 e 11.
O exemplo corrente
Finalizarei esta breve revisão apresentando o exemplo que vou usar como base para a 
maioria das discussões, se não todas, do restante do livro: o familiar – para não dizer 
banalizado – banco de dados de fornecedores e peças. (Peço desculpas por mais uma 
vez trazer à vista esse velho cavalo de batalha, mas acredito que o uso de um mesmo 
exemplo em uma variedade de livros e outras publicações possa ajudar, e não preju-
dicar, o aprendizado.) Valores de exemplo são mostrados na figura 1.3. Para elaborar:
Figura 1.3 – Banco de dados de fornecedores e peças – valores de exemplo.
Fornecedores (suppliers)
A relação S denota fornecedores (mais precisamente, fornecedores por contrato). 
Cada fornecedor tem um número de fornecedor (SNO), exclusivo para esse 
fornecedor (como você pode ver pela figura, tornei {SNO} a chave primária); 
um nome (SNAME), não necessariamente exclusivo (ainda que os valores de 
37Capítulo 1 ■ Preparando o cenário
SNAME na figura 1.3 parecem ser exclusivos); um valor de estado (STATUS), 
representando algum tipo de nível de classificação ou de preferência entre 
fornecedores disponíveis; e uma localização (CITY).
Peças (parts)
A relação P denota peças (mais precisamente, tipos de peças). Cada tipo de peça 
tem um número de peça (PNO) que é exclusivo ({PNO} é a chave primária); 
um nome (PNAME); uma cor (COLOR); um peso (WEIGHT); e uma locali-
zação onde as peças desse tipo estão armazenadas (CITY).
Entregas (shipments)
A relação SP denota entregas (ela mostra quais peças são fornecidas, ou entre-
gues, e por quais fornecedores). Cada entrega tem um número de fornecedor 
(SNO), um número de peça (PNO) e uma quantidade (QTY). Para efeito do 
exemplo, presumo que haja, em um momento qualquer, no máximo uma entre-
ga para um determinado fornecedor, e uma determinada peça ({SNO,PNO} é 
a chave primária; além disso, {SNO} e {PNO} são ambas chaves estrangeiras, 
correspondendo às chaves primárias de S e P, respectivamente). Note que o 
banco de dados da figura 1.3 inclui um fornecedor, o fornecedor S5, que não 
tem nenhuma entrega.
Modelo versus implementação
Antes de avançarmos, há um ponto importante que preciso explicar, pois sustenta 
todo o restante a ser discutido neste livro. O modelo relacional é, evidentemente, um 
modelo de dados. Infelizmente, no entanto, esse último termo tem dois significados 
bastante distintos no mundo dos bancos de dados. O primeiro e mais fundamental 
é este:
Definição: um modelo de dados (primeiro sentido) é uma definição abstrata, 
autocontida e lógica das estruturas de dados, dos operadores de dados, e assim 
por diante; reunidos, esses fatores formam a máquina abstrata com a qual os 
usuários interagem.
Esse é o significado em que pensamos quando falamos sobre o modelo relacional em 
particular. E, armados dessa definição, podemos, de modo proveitoso e importante, 
avançar para distinguir um modelo de dados, nesse primeiro sentido, de sua imple-
mentação, que pode ser definida desta forma:
Definição: uma implementação de determinado modelo de dados é uma reali-
zação física em uma máquina real dos componentes da máquina abstrata que, 
reunidos, constituem esse modelo.
SQL e Teoria Relacional38
Deixe-me ilustrar essas definições em termos do modelo relacional, especificamente. 
Em primeiro lugar, considere o conceito de relação em si. Esse conceito é parte do 
modelo: usuários têm de saber quais são as relações, têm de saber que elas são for-
madas por tuplas e atributos, têm de saber como interpretá-las,e assim por diante. 
Tudo isso é parte do modelo. Porém eles não têm de saber como as relações são fisi-
camente armazenadas no disco, como valores de dados individuais são fisicamente 
codificados ou que índices e outros caminhos de acesso existem; tudo isso é parte 
da implementação, e não parte do modelo.
Ou considere o conceito de uma junção: usuários têm de saber o que é uma junção, 
têm de saber como invocar uma junção, têm de saber qual a apresentação do resul-
tado de uma junção, e assim por diante. Novamente, tudo isso é parte do modelo. 
No entanto eles não têm de saber como as junções são fisicamente implementadas, 
quais transformações de expressão ocorrem nos bastidores, quais índices ou outros 
caminhos de acesso são utilizados ou que operações físicas de E/S ocorrem; tudo 
isso é parte da implementação, e não parte do modelo.
E mais um exemplo: chaves candidatas (chaves, para abreviar) são, uma vez mais, parte 
do modelo, e usuários definitivamente têm de saber o que as chaves são; em parti-
cular, eles têm de saber que tais chaves têm a propriedade de exclusividade. Agora, a 
exclusividade das chaves é reforçada nos sistemas atuais por meio do que é chamado 
de um “índice exclusivo”; mas índices em geral, e índices exclusivos em particular, não 
são parte do modelo, eles são parte da implementação. Assim, um índice exclusivo 
não deve ser confundido com uma chave no sentido relacional, ainda que o primeiro 
possa ser utilizado para implementar o segundo (mais precisamente, para implementar 
alguma restrição de chave – veja o capítulo 8).
Em resumo, então:
•	 O	modelo (primeiro significado) é o que o usuário precisa saber.
•	 A	implementação é o que o usuário não precisa saber.
Por favor, compreenda que não estou dizendo aqui que usuários estão proibidos de 
conhecer a implementação; estou apenas dizendo que eles não têm de fazê-lo. Em 
outras palavras, tudo que está relacionado à implementação deve estar, pelo menos 
potencialmente, escondido do usuário.
Aqui estão algumas consequências importantes das definições anteriores. Em primeiro 
lugar, observe que tudo que está relacionado ao desempenho é fundamentalmente 
uma questão de implementação, e não de modelo. Esse ponto é amplamente mal 
compreendido! Por exemplo, muitas vezes ouvimos afirmações no sentido de que 
“junções são lentas”. Porém tais afirmações simplesmente não fazem sentido. Uma 
junção é parte do modelo, e o modelo como tal não pode ser dito como sendo rápido 
39Capítulo 1 ■ Preparando o cenário
ou lento; apenas a implementação pode ser dita como detentora de qualquer quali-
dade desse tipo. Assim, podemos razoavelmente dizer que algum produto específico 
X tenha uma implementação mais rápida ou mais lenta de alguma junção específica, 
em alguns dados específicos, do que algum outro produto específico Y – mas isso é 
praticamente tudo.
Agora, não quero passar uma impressão errada aqui. É verdade que o desempenho 
é fundamentalmente uma questão de implementação; no entanto, isso não significa 
que uma boa implementação terá um bom desempenho se você utilizar o modelo 
erroneamente. Na realidade, essa é precisamente uma das razões por que você precisa 
conhecer o modelo: para que você não o utilize erroneamente. Se você escrever uma 
expressão como S JOIN SP, está dentro de seus direitos esperar que o sistema a im-
plemente com eficiência; mas se você insistir, com efeito, em codificar manualmente 
a junção, talvez desta forma (em pseudocódigo) –
do for all tuples in S ;
 fetch S tuple into TS , TN , TT , TC ;
 do for all tuples in SP with SNO = TS ;
 fetch SP tuple into TS , TP , TQ ;
 emit TS , TN , TT , TC , TP , TQ ;
 end ;
end ;
–, então não haverá como você obter um bom desempenho. Recomendação: não faça 
isso. Sistemas relacionais não devem ser utilizados como simples métodos de acesso.9
Por falar nisso, essas observações sobre desempenho também se aplicam à SQL. Assim 
como os operadores relacionais (de junção e outros), não se pode dizer que a SQL 
seja rápida ou lenta – apenas implementações podem razoavelmente ser descritas 
em tais termos –, mas também é possível usar SQL de forma a garantir um mau 
desempenho. Ainda que, em geral, eu tenha pouco a dizer sobre desempenho neste 
livro, vou ocasionalmente apontar certas implicações de desempenho naquilo que 
estou recomendando.
Nota paralela: gostaria de me aprofundar por um momento na questão de de-
sempenho. Em geral, minhas recomendações neste livro nunca têm por base 
o desempenho como um motivador principal; afinal, sempre foi um objetivo 
do modelo relacional retirar considerações de desempenho das mãos do usu-
ário e colocá-las, em vez disso, nas mãos do sistema. Entretanto, não é preciso 
dizer que esse objetivo não foi totalmente atingido, e assim (como eu já disse) 
9 Mais de um revisor observou que essa frase não fazia sentido (como um sistema pode ser utilizado 
como um método?). Bem, se você é jovem demais para estar familiarizado com o termo método 
de acesso, eu o invejo; mas a realidade é que, esse termo, ainda que inapropriado fosse (e seja), foi 
amplamente usado durante muitos anos como significando um simples recurso de E/S de nível 
de registro, de um tipo ou de outro.
SQL e Teoria Relacional40
a meta de utilizar SQL relacionalmente deve, às vezes, ser comprometida no 
interesse de se obter um desempenho satisfatório. Essa é outra razão por que, 
como disse antes neste capítulo, a regra suprema deve ser: “você pode fazer o 
que quiser, desde que saiba o que está fazendo”. Fim da nota paralela.
De volta ao modelo versus implementação, e aos pontos que surgem dessa distinção, o 
segundo ponto é que, como você provavelmente percebeu, é precisamente a separação 
de modelo e implementação que nos permite obter independência de dados físicos. A 
independência de dados físicos – não é um ótimo termo, mas parece que estamos 
presos a ele – significa que temos a liberdade de fazer mudanças na forma como os 
dados são fisicamente armazenados e acessados sem termos de fazer as mudanças 
correspondentes na forma como os dados são percebidos pelo usuário. Agora, a razão 
por que podemos querer alterar esses detalhes de armazenamento e acesso é, tipica-
mente, desempenho; e o fato de podermos fazer tais alterações sem ter de modificar 
a forma como os dados aparecem para o usuário significa que programas e consultas 
existentes, e outros elementos do tipo, podem todos ainda funcionar depois da alte-
ração. De forma muito importante, então, a independência de dados físicos significa 
proteger o investimento em treinamento de usuário e aplicações (investimento também no 
projeto de bancos de dados lógicos, devo acrescentar).
É uma consequência de tudo que acabamos de ver que, como indicado previamente, 
índices e, na realidade, caminhos de acesso físico de qualquer tipo sejam adequa-
damente parte da implementação, e não do modelo; eles pertencem aos bastidores 
e devem estar escondidos do usuário. (Note que caminhos de acesso como tais não 
são mencionados em nenhum lugar do modelo relacional.) Pelos mesmos motivos, 
eles também devem ser rigorosamente excluídos da SQL. Recomendação: evite o 
uso de qualquer construto SQL que viole esse preceito. (Na realidade, não há nada 
no padrão que o faça, até onde estou ciente, mas sei que o mesmo não é verdadeiro 
quanto a certos produtos SQL.)
De qualquer forma, como você pode ver a partir das definições anteriores, a distinção 
entre modelo e implementação é, na realidade, apenas um caso especial – um caso 
especial muito importante – da distinção habitual entre considerações lógicas e físicas 
em geral. Infelizmente, entretanto, a maioria dos sistemas SQL atuais não faz essas 
distinções tão claramente como deveria. Como consequência direta, entregam muito 
menos independência de dados físicos do que deveriam, e muito menos do que, em 
princípio, sistemas relacionais são capazes. Voltarei a essa questão na próxima seç��o.
Agora, volto-me para o segundo significadodo termo modelo de dados, com o qual, 
ouso dizer, você deve estar bastante familiarizado. Ele pode ser definido desta forma:
Definição: um modelo de dados (segundo sentido) é um modelo dos dados – 
especialmente dos dados persistentes – de alguma empresa específica.
41Capítulo 1 ■ Preparando o cenário
Em outras palavras, um modelo de dados no segundo sentido é apenas um projeto 
de banco de dados (lógico e, possivelmente, um tanto quanto abstrato). Por exem-
plo, podemos falar do modelo de dados de algum banco, algum hospital ou algum 
departamento do governo.
Tendo explicado esses dois significados distintos, gostaria de chamar sua atenção para 
uma analogia que acredito que esclareça o relacionamento entre eles:
•	 Um	modelo	de	dados	no	primeiro	sentido	é	como	uma	linguagem	de	progra-
mação, cujos construtos podem ser usados para solucionar muitos problemas 
específicos, mas que, por si só, não têm conexão direta com nenhum desses 
problemas específicos.
•	 Um	modelo	de	dados	no	segundo	sentido	é	como	um	programa	específico	
escrito nessa linguagem – ele utiliza os recursos fornecidos pelo modelo, no 
primeiro sentido do termo, para solucionar algum problema específico.
Por falar nisso, é uma consequência do que vimos que, se estamos falando sobre mo-
delos de dados no segundo sentido, então podemos razoavelmente falar de “modelos 
relacionais” no plural, ou de “um” modelo relacional (com um artigo indefinido). 
Porém, se estamos falando sobre modelos de dados no primeiro sentido, então há 
apenas um modelo relacional, e ele é o modelo relacional (com o artigo definido). Terei 
mais a dizer sobre esse último ponto no apêndice A.
Pelo restante deste livro, vou utilizar o termo modelo de dados, ou, de forma geral, 
apenas modelo, para simplificar, exclusivamente no primeiro sentido.
Propriedades de relações
Agora vamos retornar para nossa análise de conceitos relacionais básicos. Nesta seção, 
quero me concentrar em algumas propriedades das relações em si. Em primeiro lugar, 
toda relação tem um cabeçalho e um corpo: o cabeçalho é um conjunto de atributos 
(onde, pelo termo atributo, quero dizer, muito especificamente, um par nome-de-atribu-
to/nome-de-tipo, sendo que não há dois atributos com o mesmo nome de atributo), e o 
corpo é um conjunto de tuplas que se conformam a esse cabeçalho. No caso da relação 
de fornecedores (S) da figura 1.3, por exemplo, há quatro atributos no cabeçalho e cinco 
tuplas no corpo. Note, portanto, que na realidade uma relação não contém tuplas – ela 
contém um corpo, e esse corpo, por sua vez, contém as tuplas –, mas falamos geralmente 
como se as relações contivessem tuplas diretamente, por simplicidade.
Por falar nisso, ainda que esteja estritamente correto dizer que o cabeçalho consiste 
em pares nome-de-atributo/nome-de-tipo, é habitual omitir os nomes de tipo em 
figuras como a figura 1.3, e, dessa forma, agir como se o cabeçalho fosse apenas um 
conjunto de nomes de atributos. Por exemplo, o atributo STATUS tem, de fato, um 
SQL e Teoria Relacional42
tipo – INTEGER, digamos –, mas eu não o mostrei na figura 1.3. Entretanto, você 
nunca deve esquecer que ele está lá!
Em seguida, o número de atributos no cabeçalho é o grau (às vezes, a aridade), e o 
número de tuplas no corpo é a cardinalidade. Por exemplo, a relação S na figura 1.3 
tem grau 4 e cardinalidade 5; da mesma forma, a relação P dessa figura tem grau 5 
e cardinalidade 6, e a relação SP dessa figura tem grau 3 e cardinalidade 12. Nota: o 
termo grau também é usado em conexão com as tuplas10. Por exemplo, as tuplas na 
relação S são (assim como a relação S em si) todas de grau 4.
Além disso, relações nunca contêm tuplas duplicadas. Essa propriedade se verifica 
porque um corpo é definido como um conjunto de tuplas, e conjuntos em matemática 
não contêm elementos duplicados. Agora, a SQL falha aqui, como estou certo de que 
você sabe: é permitido que tabelas SQL contenham linhas duplicadas, não sendo, 
portanto, relações em geral. Por favor, compreenda, portanto, que ao longo deste 
livro vou sempre usar o termo “relação” para representar uma relação – sem tuplas 
duplicadas, por definição – e não uma tabela SQL. Compreenda também, por favor, 
que operações relacionais sempre produzem um resultado sem tuplas duplicadas, 
novamente por definição. Por exemplo, projetar a relação de fornecedores da figura 1.3 
sobre CITY produz o resultado mostrado aqui na esquerda, e não aquele da direita:
(O resultado da esquerda pode ser obtido por meio da consulta SQL SELECT 
DISTINCT CITY FROM S. Omitindo esse DISTINCT, conseguimos o resultado não 
relacional da direita. Note, em particular, que a tabela da direita não tem nenhum 
sublinhado duplo; isso porque ela não tem nenhuma chave e, portanto, nenhuma 
chave primária a fortiori.)
Além disso, as tuplas de uma relação são não ordenadas, de cima para baixo. Essa pro-
priedade se verifica porque, novamente, um corpo é definido como sendo um conjunto, 
e conjuntos em matemática não têm ordenamento em seus elementos (portanto, por 
exemplo, {a,b,c} e {c,a,b} são o mesmo conjunto em matemática, e uma afirmação 
semelhante naturalmente se aplica ao modelo relacional). Evidentemente, quando 
desenhamos uma relação como uma tabela no papel, temos realmente de mostrar as 
linhas em alguma ordem de cima para baixo, mas essa ordenação não corresponde 
a nada relacional. No caso da relação de fornecedores como representada na figura 
1.3, por exemplo, eu poderia ter mostrado as linhas em qualquer ordem – digamos 
10 Ele também é utilizado em conexão com chaves (veja o capítulo 5).
43Capítulo 1 ■ Preparando o cenário
fornecedor S3, depois S1, depois S5, depois S4, depois S2 –, e a figura ainda repre-
sentaria a mesma relação. Nota: o fato de as relações não terem ordenação para suas 
tuplas não significa que consultas não possam incluir uma especificação ORDER BY, 
mas significa, na realidade, que tais consultas produzem um resultado que não é uma 
relação. ORDER BY é útil para apresentação de resultados, mas não é um operador 
relacional como tal.
De modo semelhante, os atributos de uma relação também são não ordenados da 
esquerda para a direita, pois um cabeçalho também é um conjunto matemático. 
Novamente, quando desenhamos uma relação como uma tabela no papel, temos de 
apresentar as colunas em alguma ordem da esquerda para a direita, mas essa orde-
nação não corresponde a nada relacional. No caso da relação de fornecedores como 
representada na figura 1.3, por exemplo, eu poderia ter mostrado as colunas em qual-
quer ordem da esquerda para a direita – digamos STATUS, SNAME, CITY, SNO –, e a 
figura ainda representaria a mesma relação no modelo relacional. Incidentalmente, a 
SQL também falha aqui. Tabelas SQL têm uma ordenação da esquerda para a direita 
para suas colunas (outro motivo pelo qual tabelas SQL não são relações em geral). Por 
exemplo, estas duas figuras representam a mesma relação, mas tabelas SQL diferentes:
(As consultas SQL correspondentes são SELECT SNO, CITY FROM S e SELECT CITY, 
SNO FROM S, respectivamente. Agora, você pode estar pensando que as diferenças 
entre essas duas consultas, e entre essas duas tabelas, dificilmente sejam muito sig-
nificativas; na realidade, entretanto, elas têm algumas consequências sérias, algumas 
das quais veremos em capítulos futuros. Veja, por exemplo, a discussão do operador 
JOIN explícito da SQL no capítulo 6.)
Por fim, relações são sempre normalizadas (de forma equivalente, elas estão na primeira 
forma normal, 1NF)11. Informalmente, o que isso significa é que, em termos da figura 
tabular de uma relação, em toda intersecção de linha e coluna sempre vemos apenas 
um único valor. Mais formalmente, isso significa que toda tupla em toda relação 
contém apenas um único valor, do tipo apropriado, em cada posição de atributo. 
Nota: terei muito mais a dizer sobre essa questão particular no próximo capítulo.
Antes de encerrar esta seção, gostaria de enfatizar algo que já mencionei váriasvezes: 
mais especificamente, o fato de que há uma diferença lógica entre uma relação como 
11 “Primeira” forma normal porque, como estou certo de que você sabe, é possível definir uma série 
de formas normais “mais elevadas” – segunda forma normal, terceira forma normal e assim por 
diante – que são relevantes à disciplina do projeto de bancos de dados.
SQL e Teoria Relacional44
tal por um lado, e uma imagem de uma relação, como mostrada, por exemplo, nas 
figuras 1.1 e 1.3, por outro. Para dizer mais uma vez, os construtos nas figuras 1.1 e 1.3 
não são relações, mas, em vez disso, imagens de relações – às quais geralmente me 
refiro como tabelas, apesar do fato de tabela ser uma palavra carregada em contextos 
SQL. Evidentemente, relações e tabelas realmente têm certos pontos de semelhança, 
e, em contextos informais, é habitual, e geralmente aceitável, dizermos que elas re-
presentam o mesmo conceito. Porém quando estamos tentando ser precisos – e agora 
estou tentando ser um pouco preciso – temos realmente de reconhecer que os dois 
conceitos não são idênticos.
Como uma nota paralela, observo que, mais genericamente, há uma diferença lógica 
entre um elemento de qualquer tipo e uma imagem desse elemento. Há uma famosa 
pintura de Magritte que ilustra belamente o ponto que estou tentando defender aqui. A 
pintura é a de um cachimbo de tabaco normal, mas na parte inferior Magritte escreveu 
Ceçi n’est pas une pipe (Isto não é um cachimbo)... O sentido, é claro, é de que obvia-
mente a pintura não é um cachimbo – em vez disso, ela é a pintura de um cachimbo.
Tendo dito tudo isso, devo agora dizer também que é, na realidade, uma grande 
vantagem do modelo relacional que seu objeto abstrato básico, a relação, tenha uma 
representação tão simples no papel; é essa representação simples no papel que faz com 
que os sistemas relacionais sejam fáceis de ser usados e fáceis de ser compreendidos, 
e também facilita o raciocínio sobre a forma como tais sistemas se comportam. No 
entanto, também é, infelizmente, provável que essa representação simples realmente 
sugira alguns pontos que não sejam verdadeiros (por exemplo, que haja uma orde-
nação de tuplas de cima para baixo).
E mais um ponto adicional: como já disse, há uma diferença lógica entre uma relação 
e uma imagem de uma relação. O conceito da diferença lógica deriva de uma máxima 
de Wittgenstein:
Todas as diferenças lógicas são grandes diferenças.
Essa noção é extraordinariamente útil; como uma “ferramenta da mente”, ela é de 
grande auxílio para um raciocínio claro e preciso, e pode ser muito útil na identifica-
ção e análise de algumas confusões que são, infelizmente, muito comuns no mundo 
dos bancos de dados. Vou recorrer a ela muitas vezes nas páginas seguintes. Nesse 
meio-tempo, deixe-me destacar que já encontramos algumas diferenças lógicas im-
portantes. Aqui estão algumas delas:
•	 SQL	versus o modelo relacional.
•	 Modelo	versus implementação.
•	 Modelo	de	dados	(primeiro	sentido)	versus modelo de dados (segundo sentido).
E encontraremos muitas outras nas páginas que virão.
45Capítulo 1 ■ Preparando o cenário
Alguns pontos cruciais
Neste momento, gostaria de mencionar alguns pontos cruciais que vou elaborar em 
capítulos futuros (especialmente no capítulo 3). Os pontos em questão são estes:
•	 Todo subconjunto de uma tupla é uma tupla: por exemplo, considere a tupla do 
fornecedor S1 na figura 1.3. Essa tupla tem quatro componentes que corres-
pondem aos quatro atributos SNO, SNAME, STATUS e CITY. Se removermos 
(digamos) o componente SNAME, o que sobra ainda é realmente uma tupla: 
a saber, uma tupla com três componentes (uma tupla de grau 3).
•	 Todo subconjunto de um cabeçalho é um cabeçalho: por exemplo, considere o 
cabeçalho da relação de fornecedores na figura 1.3. Esse cabeçalho tem quatro 
atributos: SNO, SNAME, STATUS e CITY. Se removermos (digamos) os atri-
butos SNAME e STATUS, o que sobra ainda é um cabeçalho, um cabeçalho 
de grau 2.
•	 Todo subconjunto de um corpo é um corpo: por exemplo, considere o corpo da 
relação de fornecedores da figura 1.3. Esse corpo tem cinco tuplas, correspon-
dendo aos cinco fornecedores S1, S2, S3, S4 e S5. Se removermos (digamos) as 
tuplas S1 e S3, o que sobra ainda é um corpo, um corpo de cardinalidade três.
Nota: talvez eu deva afirmar apenas para registro que, ao longo deste livro – de acor-
do com a prática normal – tomarei expressões na forma “B é um subconjunto de A” 
como incluindo a possibilidade de que A e B possam ser iguais. Assim, por exemplo, 
toda tupla é um subconjunto dela mesma (e assim também todo cabeçalho, e assim 
também todo corpo). Quando quiser excluir tal possibilidade, falarei explicitamente 
em termos de subconjuntos próprios. Por exemplo, nossa tupla habitual do fornecedor 
S1 é certamente um subconjunto de si mesma, mas não é um subconjunto próprio 
de si mesma. Além disso, as afirmações anteriores aplicam-se igualmente aos super-
conjuntos, mutatis mutandis (mudando o que tem que ser mudado); por exemplo, a 
tupla do fornecedor S1 é um superconjunto de si mesma, mas não um superconjunto 
próprio de si mesma.12
Também gostaria de dizer algo sobre a noção crucial de igualdade – especialmente pelo 
fato de essa noção ser aplicada a tuplas e a relações, especificamente. Em geral, dois 
valores são iguais se – e apenas se – eles tiverem o mesmo valor. Por exemplo, o inteiro 
3 é igual ao inteiro 3, e a nada mais – em particular, ele não é igual a qualquer outro 
inteiro. Exatamente da mesma forma, duas tuplas são iguais se – e apenas se – elas 
12 O que descrevi nesse parágrafo é a convenção matemática padrão; no entanto, você pode ter 
encontrado uma convenção diferente em contextos menos formais. Para ser específico, algumas 
pessoas utilizam “B é um subconjunto de A” como significando o que quero dizer quando digo 
que B é um subconjunto próprio de A, e utilizam “B é um subconjunto de ou igual a A” como 
significando o que quero dizer quando digo que B é um subconjunto de A. Da mesma forma para 
superconjuntos, mutatis mutandis.
SQL e Teoria Relacional46
forem exatamente a mesma tupla. Com referência à figura 1.3, por exemplo, a tupla 
do fornecedor S1 é igual à tupla do fornecedor S1, e a nada mais – em particular, ela 
não é igual a qualquer outra tupla. Em outras palavras, duas tuplas são iguais se – e 
apenas se – (a) elas envolverem exatamente os mesmos atributos e os (b) valores de 
atributo correspondentes forem iguais, por sua vez.
Ademais (isso pode parecer óbvio, mas precisa ser dito), duas tuplas são duplicatas 
uma da outra se – e apenas se – elas forem iguais.
Voltando-nos agora para as relações: exatamente da mesma forma, duas relações são 
iguais se – e apenas se – elas forem exatamente a mesma relação. Com referência à 
figura 1.3, por exemplo, a relação de fornecedores é igual à relação de fornecedores 
e a nada mais – em particular, ela não é igual a qualquer outra relação. Em outras 
palavras, duas relações são iguais se – e apenas se – os seus cabeçalhos forem iguais 
e seus corpos forem iguais.
Como já disse, vou retornar a essas questões no capítulo 3. Aqui, deixe-me apenas 
acrescentar que a noção de igualdade de tuplas em particular é absolutamente fun-
damental – praticamente tudo no modelo relacional é crucialmente dependente dela, 
como veremos.
Relações de base versus relações derivadas
Como expliquei antes, os operadores da álgebra relacional nos permitem iniciar com 
algumas relações dadas, como aquelas representadas na figura 1.3, e obter relações 
adicionais a partir das primeiras (por exemplo, efetuando consultas). As relações 
dadas são referidas como relações de base, as outras são relações derivadas. Para 
darmos nosso primeiro passo, portanto, um sistema relacional tem, em primeiro 
lugar, de fornecer meios para definição dessas relações de base. Em SQL, essa tarefa 
é realizada pela instrução CREATE TABLE (a contraparte SQL para uma relação de 
base seria, é claro, uma tabela de base, queé o que CREATE TABLE cria). E relações 
de base obviamente precisam ser nomeadas – por exemplo:
CREATE TABLE S ... ;
Mas certas relações derivadas, incluindo, em particular, as que são chamadas de visões 
(views), também são nomeadas. Uma visão (também conhecida como uma relação virtual) 
é uma relação nomeada cujo valor em um tempo qualquer t é o resultado da avaliação 
de determinada expressão relacional nesse tempo t. Aqui está um exemplo SQL:
CREATE VIEW SST_PARIS AS
 ( SELECT SNO , STATUS
 FROM S
 WHERE CITY = 'Paris' ) ; 
47Capítulo 1 ■ Preparando o cenário
Em princípio, você pode operar sobre visões exatamente como se elas fossem relações 
de base13, mas elas não são relações de base. Em vez disso, você pode pensar em uma 
visão como sendo “materializada” – na prática, você pode pensar em uma relação de 
base sendo construída e cujo valor seja obtido avaliando-se a expressão relacional 
especificada – no momento em que a visão em questão é referenciada. Porém devo 
enfatizar que pensar em visões como sendo materializadas dessa forma quando elas 
são referenciadas é puramente conceitual; isso é apenas uma forma de pensar; não é 
o que deve acontecer; e não funcionaria para operações de atualização de qualquer 
forma. A forma como as visões devem realmente funcionar é explicada no capítulo 9.
Por falar nisso, há um ponto importante que preciso defender aqui. Você muitas vezes 
ouvirá a diferença entre relações de base e visões sendo descrita desta forma (cuidado! 
aí vêm algumas inverdades!):
•	 Relações	de	base	realmente	existem	–	ou	seja,	elas	são	fisicamente	armazenadas	
no banco de dados.
•	 Visões,	por	 contraste,	não	“existem	 realmente”	–	 elas	meramente	 fornecem	
formas diferentes de analisarmos as operações de base.
No entanto o modelo relacional não tem nada a dizer quanto ao que é fisicamente 
armazenado! – aliás, ele não tem nada a dizer sobre nenhuma questão de armaze-
namento físico. Em particular, ele categoricamente não diz que relações de base são 
fisicamente armazenadas. O único requisito é que haja algum mapeamento entre o 
que é fisicamente armazenado e essas relações de base, para que essas relações de base 
possam de alguma forma ser obtidas quando forem necessárias (conceitualmente, 
de qualquer modo). Se as relações de base puderem ser obtidas a partir do que quer 
que esteja fisicamente armazenado, então tudo mais também poderá. Por exemplo, 
poderíamos armazenar fisicamente a junção de fornecedores e entregas, em vez de 
armazená-las separadamente; então, relações de base S e SP poderiam ser obtidas, 
conceitualmente, tomando-se projeções apropriadas dessa junção. Em outras palavras: 
relações de base não são mais (nem menos!) “físicas” do que visões, no que se refere 
ao modelo relacional.
O fato de o modelo relacional não dizer nada sobre o armazenamento físico é deli-
berado, é claro. A ideia era fornecer a implementadores a liberdade de implementar o 
modelo da forma que escolhessem – em particular, de qualquer forma que parecesse 
produzir bom desempenho – sem comprometer a independência de dados físicos. 
O fato triste, no entanto, é que a maioria dos fornecedores de produtos SQL não 
parece ter entendido esse ponto (ou não se dispôs a enfrentar o desafio, de qualquer 
13 Talvez você esteja pensando que essa afirmação não possa ser 100% verdadeira para operações de 
atualização. Se for assim, você pode estar certo no que se refere aos produtos SQL de hoje; ainda 
assim, continuo afirmando que isso é verdade em princípio. Veja a seção “Operações de atualização” 
no capítulo 9 para discussões adicionais.
SQL e Teoria Relacional48
forma); em vez disso, eles mapeiam tabelas de base de modo razoavelmente direto ao 
armazenamento físico14, e (como mencionado previamente) seus produtos, portanto, 
oferecem muito menos independência de dados físicos do que sistemas relacionais 
são ou deveriam ser capazes. De fato, essa situação é refletida no próprio padrão SQL 
(assim como na maioria das outras documentações SQL), o qual tipicamente – quase 
sempre, aliás – fala em termos de “tabelas e visões”. Claramente, qualquer pessoa 
que fale dessa forma está com a impressão de que tabelas e visões sejam elementos 
distintos, e provavelmente também que “tabelas” sempre signifiquem especificamente 
tabelas de base e que tabelas de base sejam fisicamente armazenadas e visões não. 
Porém todo o sentido de uma visão é o de que ela é uma tabela (ou, como eu preferiria 
dizer, uma relação); ou seja, podemos efetuar os mesmos tipos de operações em visões 
que podemos efetuar em relações regulares (pelo menos no modelo relacional), pois 
visões são “relações regulares”. Ao longo deste livro, portanto, utilizarei o termo relação 
para representar uma relação (possivelmente uma relação de base, possivelmente uma 
visão, possivelmente um resultado de consulta, e assim por diante); e, se quiser me 
referir a uma relação de base especificamente, direi “relação de base”. Recomendação: 
sugiro veementemente que você adote a mesma disciplina. Não caia na armadilha 
habitual de pensar que o termo relação significa especificamente uma relação de 
base – ou, em termos SQL, de pensar que o termo tabela significa especificamente 
uma tabela de base. Da mesma forma, não caia na armadilha habitual de pensar que 
relações de base (ou tabelas de base, em SQL) têm de ser fisicamente armazenadas.
Relações versus relvars
Agora, é inteiramente possível que você já soubesse tudo que vim lhe dizendo até 
aqui neste capítulo; aliás, até espero que você saiba, apesar de também esperar que 
isso não signifique que você tenha achado o material maçante. De qualquer forma, 
agora abordarei algo que você pode ainda não conhecer. O fato é que historicamente 
tem havido muita confusão sobre mais uma diferença lógica: mais precisamente, 
aquela entre relações como tais por um lado, e variáveis de relações (relation variables) 
por outro.
Esqueça os bancos de dados por um momento; considere, em vez disso, o simples 
exemplo de linguagem de programação a seguir. Vamos supor que eu diga, em alguma 
linguagem de programação:
DECLARE N INTEGER ... ;
14 Digo isso totalmente consciente de que a maioria dos produtos SQL de hoje de fato fornece opções 
para operações de hash, particionamento, indexação, agrupamento, entre outras formas de orga-
nização dos dados armazenados em disco. Apesar dessa situação, ainda considero o mapeamento 
entre tabelas de base e armazenamento físico nesses produtos como razoavelmente direto.
49Capítulo 1 ■ Preparando o cenário
Então, N aqui não é um inteiro. Em vez disso, ele é uma variável, cujos valores são in-
teiros como tais –inteiros diferentes em momentos distintos. Todos nós entendemos 
isso. Bem, exatamente da mesma forma, se digo em SQL
CREATE TABLE T ... ;
então T não é uma tabela. Ela é uma variável, uma variável de tabela ou (como preferiria 
dizer, ignorando diversas peculiaridades SQL tais como linhas duplicadas e ordena-
ção de colunas da esquerda para a direita) uma variável de relação, cujos valores são 
relações como tais (relações diferentes em momentos distintos).
Dê mais uma olhada na figura 1.3 – o banco de dados de fornecedores e peças. Essa 
figura mostra três valores – mais especificamente, valores de relação que chegam a 
existir no banco de dados em algum momento específico. No entanto, se fôssemos 
verificar o banco de dados em algum momento distinto, provavelmente veríamos três 
valores de relação diferentes sendo mostrados no lugar deles. Em outras palavras, S, P 
e SP nesse banco de dados são realmente variáveis: variáveis de relação, para sermos 
precisos. Por exemplo, vamos supor que a variável de relação S atualmente tenha o valor 
mostrado na figura 1.3 – o valor de relação, quer dizer – e vamos supor que excluamos 
o conjunto de tuplas (na realidade há apenas uma) para fornecedores em Atenas:
DELETE S WHERE CITY = 'Athens' ;
Aqui está o resultado:
Conceitualmente, o que aconteceu aqui é que o valor

Mais conteúdos dessa disciplina