You are on page 1of 145

Br asíl i a-DF, 2011.

Si st emas de Banc o de Dados
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
2
Elaboração:
Taylor Montedo Machado
Produção:
Equipe Técnica de Avaliação, Revisão Linguística e Editoração
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
3
Sumário
Apresentação...........................................................................................................................................
Organização do Caderno de Estudos e Pesquisa ...................................................................................
Organização da Disciplina ......................................................................................................................
Introdução ...............................................................................................................................................
Unidade I – Introdução à Modelagem Conceitual ................................................................................
Capítulo 1 – Bancos de Dados e seus Usuários ..........................................................................
Capítulo 2 – Conceitos e Arquiteturas de um SGBD ...................................................................
Capítulo 3 – Modelagem de Dados Utilizando o MER .................................................................
Unidade II – Introdução à Modelagem Conceitual ...............................................................................
Capítulo 4 – Modelo de Dados Relacional ..................................................................................
Capítulo 5 – Projeto de Banco de Dados Relacional Utilizando o MER .........................................
Capítulo 6 – SQL – Structured Query Language .........................................................................
Unidade III – Teoria e Metodologia do Projeto de Banco de Dados ....................................................
Capítulo 7 – Dependência Funcional e Normalização ..................................................................
Capítulo 8 – Metodologia para Projeto Prático de Banco de Dados .............................................
Unidade IV – Armazenagem de Dados, Indexação, Processamento de Consultas e Projeto Físico ..
Capítulo 9 – Algoritmos para Processamento e Otimização de Consultas ...................................
Capítulo 10 – Técnicas de Controle de Concorrência .................................................................
Capítulo 11 – Técnicas de Recuperação de Dados .....................................................................
Para (não) Finalizar ................................................................................................................................
Referências ..............................................................................................................................................
Apêndice I – Palavras-Chave do SQL ....................................................................................................
Apêndice II – Expressões de Valor ........................................................................................................
Apêndice III – Comandos SQL ...............................................................................................................
04
05
06
07
09
09
16
28
41
41
48
52
81
81
92
95
95
99
108
122
123
124
137
143
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
4
Caro aluno,
Bem-vindo ao estudo da disciplina Sistemas de Banco de Dados.
Este é o nosso Caderno de Estudos e Pesquisa, material elaborado com o objetivo de contribuir para a realização e o
desenvolvimento de seus estudos, assim como para a ampliação de seus conhecimentos.
Para que você se informe sobre o conteúdo a ser estudado nas próximas semanas, conheça os objetivos da disciplina, a
organização dos temas e o número aproximado de horas de estudo que devem ser dedicadas a cada unidade.
A carga horária desta disciplina é de 80 (oitenta) horas, cabendo a você administrar o tempo conforme a sua disponibilidade.
Mas, lembre-se, há uma data-limite para a conclusão do curso, incluindo a apresentação ao seu tutor das atividades
avaliativas indicadas.
Os conteúdos foram organizados em unidades de estudo, subdivididas em capítulos, de forma didática, objetiva e
coerente. Eles serão abordados por meio de textos básicos, com questões para reflexão, que farão parte das atividades
avaliativas do curso; serão indicadas, também, fontes de consulta para aprofundar os estudos com leituras e pesquisas
complementares.
Desejamos a você um trabalho proveitoso sobre os temas abordados nesta disciplina. Lembre-se de que, apesar de
distantes, podemos estar muito próximos.
A Coordenação
Apresentação
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
5
Organização do Caderno de Estudos e Pesquisa
Apresentação: Mensagem da Coordenação.
Organização da Disciplina: Apresentação dos objetivos e da carga horária das unidades.
Introdução: Contextualização do estudo a ser desenvolvido por você na disciplina, indicando a importância desta para
sua formação acadêmica.
Ícones utilizados no material didático
Provocação: Pensamentos inseridos no material didático para provocar a reflexão sobre sua prática e
seus sentimentos ao desenvolver os estudos em cada disciplina.
Para refletir: Questões inseridas durante o estudo da disciplina para estimulá-lo a pensar a respeito
do assunto proposto. Registre sua visão sem se preocupar com o conteúdo do texto. O importante é
verificar seus conhecimentos, suas experiências e seus sentimentos. É fundamental que você reflita
sobre as questões propostas. Elas são o ponto de partida de nosso trabalho.
Textos para leitura complementar: Novos textos, trechos de textos referenciais, conceitos de
dicionários, exemplos e sugestões, para lhe apresentar novas visões sobre o tema abordado no texto
básico.
Sintetizando e enriquecendo nossas informações: Espaço para você fazer uma síntese dos textos
e enriquecê-los com sua contribuição pessoal.
Sugestão de leituras, filmes, sites e pesquisas: Aprofundamento das discussões.
Praticando: Atividades sugeridas, no decorrer das leituras, com o objetivo pedagógico de fortalecer o
processo de aprendizagem.
Para (não) finalizar: Texto, ao final do Caderno, com a intenção de instigá-lo a prosseguir com a
reflexão.
Referências: Bibliografia consultada na elaboração da disciplina.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
6
Organização da Disciplina
Ementa:
Sistemas de banco de dados. Sistemas de gerenciamento de banco de dados. Modelagem de dados. Modelos conceituais. O
modelo relacional. Normalização. A linguagem SQL. Projeto de banco de dados. Implementação de SGBDs. Armazenamento
de dados. Estruturas de índices. Processamento e otimização de consultas. Processamento de transações. Controle de
concorrência. Recuperação.
Objetivos:
– Contribuir para a capacitação do participante quanto à análise, planejamento, estruturação e implementação
de sistemas de gerenciamento de banco de dados.
– Apresentar aos participantes os principais conceitos sobre modelagem, projeto, implementação de
sistemas de gerenciamento de banco de dados.
– Estimular a conscientização das potencialidades e restrições inerentes aos sistemas de gerenciamento de
banco de dados.
Unidade I – Introdução à Modelagem Conceitual
Carga horária: 20 horas
Conteúdo Capítulo
Banco de Dados e seus Usuários 1
Conceitos e Arquiteturas de um SGBD 2
Modelagem de Dados Usando o MER 3
Unidade II – Introdução à Modelagem Conceitual
Carga horária: 20 horas
Conteúdo Capítulo
O Modelo de Dados Relacional 4
Projeto de Banco de Dados Relacional Utilizando o MER 5
SQL – Structured Query Language 6
Unidade III – Teoria e Metodologia do Projeto de Banco de Dados
Carga horária: 20 horas
Conteúdo Capítulo
Dependência Funcional e Normalização 7
Metodologia para Projeto Prático de Banco de Dados 8
Unidade IV – Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico
Carga horária: 20 horas
Conteúdo Capítulo
Algoritmos para processamento e Otimização de Consultas 9
Técnicas de Controle de Concorrência 10
Técnicas de Recuperação de Dados 11
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
7
Introdução
Ao olharmos para os processos modernos que nos prestam serviços ou mesmo nos que somos os próprios prestadores de
serviços, é possível inferir que existem gigantescas bases de dados que dão suporte ou até mesmo gerenciam nossas vidas.
Questões como a nossa conta bancária. As instituições bancárias mantêm bancos de dados que permitem o gerenciamento
de todas as transações financeiras realizados. São esses registros que permitem que seja possível acompanhar saldos,
aplicações, saques e manter todo histórico de cada conta de cada cliente.
Processos como a apuração das eleições ou mesmo o processamento da declaração do imposto de renda também são
suportados por bancos de dados mantidos pelo governo e que permitem que seja possível, como no caso deste último,
acompanhar o histórico de cada cidadão.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
8
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
9
Capítulo 1 – Bancos de Dados e seus Usuários
Hoje em dia o termo banco de dados é bastante popular em diversas
áreas de atuação. Com o aumento da utilização de computadores na
manipulação de dados que envolvem diversas aplicações, os bancos
de dados estão sendo desenvolvidos e aplicados nas diferentes
áreas que envolvem o comércio, a indústria, a pesquisa acadêmica,
entre outras.
1. Introdução
Segundo Silberschatz (2006), um banco de dados é um conjunto de dados inter-relacionados. Podemos afirmar que
esses bancos possuem informações que representam o dia a dia de uma empresa, de uma loja, de uma locadora de vídeo,
enfim, de qualquer ambiente que possa ter suas informações coletadas e representadas de uma forma organizada. Tais
bancos de dados, além de manter todo esse volume de dados organizado, também devem permitir atualizações, inclusões e
exclusões de dados, sem nunca perder a consistência. E, além disso, é necessário considerar que muitas vezes estaremos
lidando com vários acessos simultâneos e concorrentes em várias partes diferentes de nosso banco de dados.
Heuser (2001) define dado como sendo um fato do mundo real que está registrado e possui um significado implícito no
contexto de um domínio de aplicação. Um banco de dados possui as seguintes propriedades:
• é uma coleção lógica coerente de dados com um significado inerente; uma disposição desordenada dos dados
não pode ser referenciada como um banco de dados;
• é projetado, construído e populado com dados para um propósito específico; um banco de dados possui um
conjunto pré-definido de usuários e aplicações;
• é representado por algum aspecto do mundo real, o qual é chamado de minimundo; qualquer alteração efetuada
no minimundo é automaticamente refletida no banco de dados.
Um banco de dados pode ser criado e mantido por um conjunto de aplicações desenvolvidas especialmente para a
tarefa, denominada Sistema de Gerenciamento de Banco de Dados (SGBD). Um SGBD permite aos usuários criar e
manipular bancos de dados de propósitos gerais. Silberschatz (2006) define SGBD como sendo uma coleção de dados
inter-relacionados e um conjunto de programas para acessar esses dados.
Unidade I
Introdução à Modelagem Conceitual
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
10
Introdução à Modelagem Conceitual Unidade I
1.1. Metadados
Uma característica importante da abordagem Banco de Dados é que o SGBD mantém não somente os dados, mas
também a forma como esses são armazenados, uma vez que contém uma descrição completa do banco de dados.
Essas informações são armazenadas no catálogo do SGBD, o qual contém informações como a estrutura de cada arquivo,
o tipo e o formato de armazenamento de cada tipo de dado, restrições. Segundo Heuser (2001), o conjunto de informações
armazenadas no catálogo de dados é denominado Metadados.
No processamento tradicional de arquivos, o programa que irá manipular os dados deve conter este tipo de informação,
ficando limitado a manipular as informações que ele conhece. Por outro lado, utilizando a abordagem banco de dados, a
aplicação pode manipular diversas bases de dados diferentes.
1.2. Programas versus Dados
O processamento tradicional de arquivos pressupõe que a estrutura de dados está incorporada ao próprio programa de
acesso. Assim sendo, uma alteração na estrutura de arquivos resulta na alteração do código fonte de todos os programas.
Porém, a abordagem de banco de dados permite que as alterações sejam efetuadas apenas no catálogo de dados, sem
necessitar alterações nos programas de acesso.
1.3. Abstração de Dados
Uma das funções de um SGBD é fornecer aos usuários uma representação conceitual dos dados sem que, para tanto,
necessite fornecer muitos detalhes de como os dados estão armazenados.
Um Modelo de Dados é uma forma de abstração dos dados que é utilizada para fornecer essa representação conceitual,
utilizando conceitos lógicos como objetos, suas propriedades e seus relacionamentos (ALVES, 2004).
Os níveis de abstração têm como função, inclusive, ocultar a complexidade e simplificar o processo de interação com os
usuários. Sob esse ponto de vista, podemos classificar a abstração em três níveis (SILBERSCHATZ, 2006).
• Físico: é o nível de abstração mais baixo e descreve como os dados são realmente armazenados no banco de
dados. Nesse nível, um registro de dado pode ser descrito como um bloco consecutivo de memória.
• Lógico: é nível de abstração intermediário, que descreve que os dados estão armazenados no banco de dados
e quais são as relações existentes entre eles. Nesse nível, um registro de dado é descrito por um tipo definido
(como um tipo em linguagem de programação) e as inter-relações entre dados são definidas.
• Visualização: é o nível de abstração mais alto, que descreve a parte do banco de dados de maior interesse
para o usuário final. Nesse nível, podemos dizer que se trata de subconjunto de dados que podem existir
apenas durante a execução de uma operação.
1.4. Múltiplas Visões de Dados
Uma vez que um banco de dados deve permitir o acesso de um conjunto diverso de usuários a todo o seu conteúdo, é
possível inferir que cada usuário, ou grupo de usuários, pode ter uma necessidade específica. Desse modo, é necessário
que cada conjunto de usuário tenha a possibilidade de ter visões diferentes da base de dados.
Assim, uma visão é definida como um subconjunto de uma base de dados, formando desse modo, um conjunto virtual
de informações (SILBERSCHATZ, 2006).
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
11
Introdução à Modelagem Conceitual Unidade I
2. Usuários
Em todo grande banco de dados existe um grande número de pessoas envolvidas que varia desde sua concepção e seu
projeto até sua manutenção.
2.1. Administrador de Banco de Dados (DBA)
Um ambiente de banco de dados envolve vários recursos que vão desde o banco de dados em si até o SGBD e outros
softwares. Cabe ao Administrador de Banco de Dados (DBA) o seu gerenciamento, envolvendo tarefas como a
autorização de acesso a ele, a sua coordenação e a monitoração de seu uso.
2.2. Projetista de Banco de Dados
Cabe ao Projetista de Banco de Dados a identificação dos dados que devem ser armazenados, bem como a definição
da estrutura adequada para representá-los e armazená-los. É função do projetista também avaliar as necessidades de
cada grupo de usuários para definir as visões que serão necessárias, integrando-as, fazendo com que o banco de dados
seja capaz de atender a todas as necessidades dos usuários.
2.3. Usuários Finais
Os usuários finais são as pessoas que utilizam o banco de dados fazendo consultas, atualizações e gerando documentos.
Podemos agrupar esses usuários em três categorias:
• casuais: acessam o banco de dados casualmente, mas podem necessitar de diferentes informações a cada
acesso; utilizam sofisticadas linguagens de consulta para especificar suas necessidades;
• novatos ou paramétricos: utilizam porções predefinidas do banco de dados, valendo-se de consultas
preestabelecidas que já foram exaustivamente testadas;
• usuários avançados: são usuários que estão familiarizados com o SGBD e realizam consultas complexas.
2.4. Analistas de Sistemas e Programadores de Aplicações
Os Analistas de Sistemas são responsáveis pela determinação dos requisitos dos usuários finais e pelo desenvolvimento
das especificações para atender aos requisitos mapeados. Por sua vez, os Programadores são responsáveis pela
implementação das especificações definidas na forma de programas, testando, depurando, documentando e dando
manutenção.
3. Esquemas de Dados
Segundo Silberschatz (2006), os esquemas de dados dizem respeito ao projeto geral do banco de dados e é um aspecto
que raramente é modificado.
Um esquema de base de dados é especificado durante o projeto da base de dados e a forma de visualização de um
esquema é chamada Diagrama do Esquema.
Os SGBDs possuem vários esquemas de banco de dados que variam em função do nível de abstração dos dados:
• esquema físico: tem como objetivo descrever o projeto do banco de dados no nível físico;
• esquema lógico: diz respeito à descrição do banco de dados no nível lógico;
• subesquema de visualização: diz respeito à descrição das visualizações possíveis para um banco de dados.
Muitos modelos de dados têm certas convenções para, diagramaticamente, mostrar esquemas especificados neles.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
12
Introdução à Modelagem Conceitual Unidade I
Alguns autores defendem que uma das maiores contribuições dos primeiros SGBDs foi introduzir a separação entre os
dados armazenados e a descrição da estrutura dos dados, o esquema de dados.
4. Vantagens e desvantagens do uso de um SGBD
Como toda e qualquer ferramenta, o uso de banco de dados apresenta um conjunto de vantagens e desvantagens quanto
ao seu uso.
4.1. Desvantagens
4.1.1. Altos Custos
As organizações têm se tornado cada vez mais complexas e os processos de negócio, por sua vez, refletem a necessidade
da disponibilidade de dados de forma rápida, precisa e flexível. Como conseqüência, os bancos de dados acabam por se
tornar cada vez mais complexos, volumosos e onerosos.
Apesar dos custos relativos ao armazenamento de dados estarem sendo reduzidos em ritmo acelerado, juntamente com
a popularização do hardware necessário, aspectos como a concepção, o gerenciamento e a manutenção de bancos de
dados cada vez mais pesam no orçamento de seu projeto. Por vezes, os custos podem se tornar um empecilho para a
adoção de um banco de dados.
4.1.2. Gerenciamento e Manutenção
A par e passo com a evolução da necessidade de informações, os bancos de dados também necessitam de manutenção
evolutiva e/ou corretiva. Uma vez que um processo na organização, que é suportado por um banco de dados, sofre alguma
mudança, a necessidade de informações para geri-lo adequadamente também muda. Além disso, a evolução tecnológica
dos SGBDs imprime a necessidade de ajustes de versão de software e/ou upgrades para que seja possível usufruir dos
benefícios que estes sistemas oferecem.
Desse modo, a necessidade de uma estrutura para gerenciar o banco de dados, bem como a necessidade de mantê-lo,
gera custos que podem tornar o seu uso proibitivo.
4.2. Vantagens
4.2.1. Controle de Redundância
No processamento tradicional de tratamento de arquivos, é necessário que cada grupo de usuários mantenha seu próprio
conjunto de arquivos e dados, o que pode fazer com que acabe ocorrendo redundâncias que prejudiquem o sistema com
problemas como:
• toda vez que for necessário atualizar um arquivo de um grupo, todos os grupos devem ser atualizados para
manter a integridade dos dados no ambiente como um todo;
• a redundância desnecessária de dados leva ao armazenamento excessivo de informações, ocupando espaço
que poderia estar sendo utilizado com outras informações.
4.2.2. Compartilhamento de Dados
A utilização de um SGBD permite que múltiplos usuários acessem o banco de dados ao mesmo tempo, permitindo que
múltiplas aplicações integradas possam acessá-lo.
O SGBD multiusuário necessita manter o controle de acessos simultâneos (concorrência) para assegurar a qualidade
do resultado de atualizações, bem como fornecer recursos que permitam a construção de múltiplas visões.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
13
Introdução à Modelagem Conceitual Unidade I
4.2.3. Restrição a Acesso não Autorizado
Um SGBD permite que seja criado um subsistema de autorização e segurança, o qual é utilizado pelo DBA para criar
contas de acesso e especificar as restrições de cada conta, sendo estendido tanto para acesso aos dados quanto ao
uso de softwares inerentes ao SGBD.
4.2.4. Representação de Relacionamentos Complexos entre Dados
Um banco de dados permite que seja catalogada uma variedade de dados que estão inter-relacionados de várias formas.
Por sua vez, um SGBD fornece uma série de recursos para representar uma grande variedade de relacionamentos entre
os dados, bem como recuperá-los e atualizá-los de maneira prática e eficiente.
4.2.5. Padronização
A abordagem de base de dados permite que o DBA defina e obrigue a padronização entre os usuários da base de dados
em grandes organizações. Isso facilita a comunicação e a cooperação entre vários departamentos, projetos e usuários.
Padrões podem ser definidos para formatos de nomes, elementos de dados, telas, relatórios, terminologias.
É possível utilizar esse recurso, com maior facilidade, em um ambiente de base de dados centralizado, em comparação
com um ambiente onde cada usuário ou grupo tem o controle de seus próprios arquivos e programas de aplicação.
4.2.6. Flexibilidade
Mudanças nos requisitos podem acarretar a necessidade de modificações na estrutura de um banco de dados. Por
exemplo, um novo grupo de usuários pode surgir com necessidade de informações adicionais, ainda não disponíveis na
base de dados. Alguns SGBDs permitem que tais mudanças na estrutura da base de dados sejam realizadas sem afetar
a maioria dos programas de aplicações existentes.
4.2.7. Redução do Tempo de Desenvolvimento de Aplicações
Uma das características mais significativas da abordagem de base de dados é o tempo reduzido para o desenvolvimento
de novas aplicações, como a recuperação de certos dados da base de dados para a impressão de novos relatórios.
Projetar e implementar uma nova base de dados pode tomar mais tempo do que escrever uma simples aplicação
especializada de arquivos. Porém, uma vez que a base de dados esteja em uso, geralmente é bastante reduzidoo tempo
para se criar novas aplicações, usando-se os recursos de um SGBD. O tempo para se desenvolver uma nova aplicação em
um SGBD é estimado em 1/4 a 1/6 do tempo de desenvolvimento, usando-se apenas o sistema de arquivos tradicional,
devido às facilidades de interfaces disponíveis em um SGBD.
4.2.8. Disponibilidade de Informações Atualizadas
A abordagem de banco de dados permite que tão logo um usuário modifique uma base de dados, todos os outros usuários
podem usufruir imediatamente dessa modificação. Essa disponibilidade de informações atualizadas é essencial para muitas
aplicações, tais como sistemas de reservas de passagens aéreas ou bases de dados bancárias.
4.2.9. Economia de Escala
A abordagem de banco de dados permite a consolidação de dados e de aplicações, reduzindo-se, desse modo, o desperdício
em atividades redundantes de processamento em diferentes projetos ou departamentos.
4.3. Quando não Utilizar um SGBD
Não raro, o uso de um SGBD pode representar um acréscimo desnecessário de custos, se comparado à abordagem de
processamento tradicional de arquivos. Exemplificando, podemos ter:
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
14
Introdução à Modelagem Conceitual Unidade I
• alto investimento inicial na compra de software e hardware adicionais;
• generalidade que um SGBD fornece na definição e processamento de dados;
• sobrecarga na provisão de controle de segurança, de controle de concorrência, na recuperação e na integração
de funções.
É necessário reconhecer que problemas adicionais podem ocorrer como da resultado especificação inadequada do projeto
e/ou da implementação das aplicações de forma não apropriada. Caso o DBA não administre o banco de dados de forma
adequada, tanto a segurança quanto a integridade dos sistemas podem ser comprometidas. A sobrecarga causada pelo
uso de um SGBD e a má administração justificam a utilização da abordagem de processamento tradicional de arquivos
em casos como:
• o banco de dados e as aplicações sejam simples, bem-definidos e não sejam esperadas mudanças no projeto;
• sejá necessário processamento em tempo real de certas aplicações, que são terrivelmente prejudicadas pela
sobrecarga causada pelo uso de um SGBD;
• não haja múltiplo acesso ao banco de dados.
5. Um Breve Histórico da Aplicação de Banco de Dados
Entre a década de 1950 e o início dos anos 1960, as fitas magnéticas eram utilizadas para o armazenamento de dados
e as tarefas de processamento de dados eram efetuadas quase que de forma mecanizada. Os registros também podiam
ser alimentados por decks de cartão perfurado e necessitavam que fossem carregados seqüencialmente, na mesma
ordem em que estavam gravados nas fitas magnéticas.
No final dos anos 1960, a tecnologia de armazenamento em discos rígidos levou a uma mudança radical no cenário do
processamento de dados, pois permitiam o acesso direto aos dados, independentemente de sua posição no disco.
Entre as décadas de 1960 e 1970, várias pesquisas foram desenvolvidas no sentido de desenvolver tecnologias que
permitissem a simplificação dos processos de escritório que conduziram à automação. Tarefas como armazenar e organizar
arquivos, que dependiam única e exclusivamente de mão-de-obra intensiva, poderiam ser simplificadas com o uso de
soluções mecânicas mais eficientes e mais baratas. Desse modo, muitas pesquisas foram desenvolvidas e resultaram na
criação dos modelos hierárquicos, de rede e relacionais.
Nesse cenário, empresas, como a IBM, tomaram a dianteira e, em 1970, um pesquisador daquela empresa, Ted Codd,
publicou o primeiro artigo sobre bancos de dados relacionais, que tratava de um método que permitia que usuários
não técnicos pudessem armazenar e recuperar grande quantidade de dados, a partir da utilização de comandos que
manipulassem dados armazenados em tabelas.
Na década de 1980, com base nesse estudom, a IBM montou um grupo de pesquisa conhecido como Sistema R (System R)
que objetivava a criação de um banco de dados relacional que tivesse viabilidade comercial. O primeiro sistema comercial
baseado no conceito desenvolvido pela IBM, foi lançado em 1976 pela Honeywell Information Systems Inc. No entanto,
o primeiro SGBD construído nos padrões SQL só começou a surgir no mercado a partir do início da década de 1980 com
o Oracle 2, da empresa Oracle, e, posteriormente, com o SQL/DS, da IBM.
No início da década de 1990, um dos produtos do Sistema R foi a criação de uma linguagem denominada SQL –
Structured Query Language (Linguagem de Consulta Estruturada). A linguagem SQL tornou-se um padrão na indústria
para bancos de dados relacionais e hoje em dia, é um padrão ISO (International Organization for Standardization
1
), o
que permitiu o desenvolvimento e refinamento de softwares de banco de dados relacionais. Outros aspectos relevantes
que contribuíram para o refinamento e popularização dos bancos de dados relacionais foram: o retorno que os usuários
desses sistemas davam para o aprimoramento da linguagem, o desenvolvimento de sistemas para novas indústrias e
1 A ISO é a organização internacional de padronização responsável pelos padrões técnicos internacionais
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
15
Introdução à Modelagem Conceitual Unidade I
aumento do uso de computadores pessoais e sistemas distribuídos. O padrão SQL passou da IBM para a ANSI (American
National Standards Institute) – Instituto Nacional Americano para Padrões que, juntamente com a ISO, formaram um
grupo de trabalho para continuar o desenvolvimento. Este desenvolvimento ainda acontece com outras novas versões
dos padrões definidos até os dias atuais.
O final da década de 1990 foi marcado pela massificação do uso da World Wide Web (WWW), fazendo com que
os sistemas de banco de dados tivessem de trabalhar com taxas de processamento de transação cada vez maiores e
disponibilidade de 24x7, ou seja, disponibilidade 24 horas por dia, 7 dias por semana.
Em meados de 2000, surge a Linguagem Extensível de Formatação ou Extended Markup Language (XML) como
uma nova tecnologia de banco de dados. O XML é uma especificação técnica desenvolvida pela W3C – World Wide
Web Consortium
1
.

1 A W3C é a entidade responsável pela definição da área gráfica da internet. (http://www.w3.org).
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
16
Introdução à Modelagem Conceitual Unidade I
Capítulo 2 – Conceitos e Arquiteturas de um SGBD
Tenha certeza da completa compreensão das informações
organizacionais durante o estudo de Modelagem Conceitual, pois
inseguranças durante os estágios posteriores da disciplina podem
ser extremamente caras, prejudicando a aprendizagem.
1. Modelos de Dados, Esquemas e Instâncias
1.1. Esquemas e Instâncias
Uma distinção importante para qualquer modelo de dados é a que deve ser feita entre a descrição do banco de dados e o
próprio banco. A descrição de um banco de dados é chamada de esquema de um banco de dados e é especificada durante
o projeto do banco de dados. Geralmente, poucas mudanças ocorrem no esquema do banco de dados.
Uma instância
1
do banco de dados diz respeito à coleção de dados armazenados em um banco de dados em um determinado
momento (SILBERSCHATZ, 2006). A instância modifica toda vez que uma alteração no banco de dados é feita. O SGBD é
responsável por garantir que toda instância do banco de dados satisfaça o seu esquema do banco de dados, respeitando
sua estrutura e suas restrições.
O esquema de um banco de dados também pode ser chamado de intensão de um banco de dados e a instância, de extensão
de um banco de dados.
A diferenciação entre esquema e instância de um banco de dados pode ser melhor compreendida fazendo uma analogia
com um programa, conforme ilustrado na Figura 2.1.
Figura 2.1 Analogia entre um Programa e um Banco de Dados
Declaração da
Variável
Esquema do Banco de
Dados
PROGRAMA BANCO DE DADOS
Valor da
Variável
Instância do Banco de
Dados
1.2. Modelos de Dados
Uma das vantagens mais relevantes de um banco de dados é a possibilidade de fornecer alguns níveis de abstração de
dados para o usuário final, omitindo os detalhes de como estes são armazenados.
1 Também pode ser chamada de ocorrência ou estado de um banco de dados
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
17
Introdução à Modelagem Conceitual Unidade I
Segundo Silberschatz, um Modelo de Dados é uma coleção de ferramentas conceituais para descrever dados, relações
de dados, semântica de dados e restrições de consistência. Um modelo de dados permite descrever a estrutura
1
de
um banco de dados de forma lógica e física. Além disso, vários Modelos de Dados também definem um conjunto de
operações para especificar como recuperar e modificar a base de dados.
Desse modo, podemos dizer que o Modelo de Dados é a principal ferramenta que fornece a abstração a um BD.
Os modelos de dados podem ser basicamente de dois tipos:
• alto nível: ou modelo conceitual de dados, que fornece uma visão mais próxima do modo como os usuários
realmente visualizam os dados;
• baixo nível: ou modelo físico de dados, que fornece uma visão mais detalhada do modo como os dados estão
realmente armazenados no computador.
1.2.1. Modelo de Dados Hierárquico
O primeiro modelo de dados a ser reconhecido foi o modelo hierárquico, que só pôde ser desenvolvido devido à consolidação
dos discos de armazenamento endereçáveis. Esses discos possibilitaram a exploração de sua estrutura de endereçamento
físico para viabilizar a representação hierárquica das informações.
No modelo hierárquico, os dados são estruturados em hierarquias ou árvores. Os nós das hierarquias contêm ocorrências
de registros, onde cada registro é uma coleção de campos (atributos), cada um contendo apenas uma informação.
O registro-pai é o registro da hierarquia que precede a outros, sendo esses outros denominados registros-filhos. Uma
ligação é uma associação entre dois registros. Possui cardinalidade 1:N o relacionamento entre um registro-pai e vários
registros-filhos.
Organizando os dados segundo o modelo hierárquico, esses podem ser acessados por meio de uma seqüência hierárquica
com uma navegação do topo para as folhas e da esquerda para a direita. Um registro pode estar associado a vários
registros diferentes, desde que seja replicado.
O Information Management System da IBM Corp (IMS) foi o sistema comercial mais divulgado no modelo hierárquico.
Uma boa parte das restrições e consistências de dados estava contida dentro dos programas escritos para as aplicações
Para acessar o banco de dados, era necessário escrever os programas na ordem.
O esquema de um banco de dados hierárquico é descrito por meio de um diagrama de estrutura de árvore. Tal diagrama
consiste em dois componentes básicos: Caixas, as quais correspondem aos tipos de registros, e Linhas, que correspondem
às ligações entre os tipos de registros. Como exemplo do modelo hierárquico, considere a Figura 2.2.
Figura 2.2. Diagrama de Estrutura de Árvore Cliente-Conta Corrente
Nome Rua Cidade
N
o
Conta Corrente Saldo
João R121 Brasília
51935 100,00
Pedro R231 Guará
61893 500,00

Fonte: Adaptado de Silberschatz (2006).
1 Por estrutura podemos compreender o tipo dos dados, os relacionamentos e as restrições que podem recair sobre os dados.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
18
Introdução à Modelagem Conceitual Unidade I
O Modelo Hierárquico apresenta algumas restrições devido a:
• complexidade dos diagramas de estrutura de árvore;
• não permitir ciclos no gráfico básico de um diagrama de estrutura de árvore;
• existência de restrições à cardinalidade dos links (de muitos para muitos (N:M) e de muitos para um (N:1));
• ausência de facilidades de consultas declarativas;
• necessidade de navegação por ponteiros para acesso à informações;
• alta complexidade das consultas.
Além disso, a replicação possui duas grandes desvantagens: pode causar inconsistência de dados, quando houver
atualização, e o desperdício de espaço é inevitável.
1.2.2. Modelo de Dados de Rede
O surgimento do modelo de rede deu-se como uma extensão ao modelo hierárquico; dessa forma, foi eliminando o conceito
de hierarquia e permitindo que um mesmo registro estivesse envolvido em várias associações.
Os registros, no modelo em rede, são organizados em grafos onde aparece um único tipo de associação (set) que define
uma relação 1:N entre 2 tipos de registros: proprietário e membro. Nesse sentido, é possível construir um relacionamento
M:N entre A e D, dados dois relacionamentos 1:N entre os registros A e D e entre os registros C e D.
Com linguagem própria para definição e manipulação de dados, o gerenciador Data Base Task Group (DBTG) da CODASYL
(Committee on Data Systems and Languages) estabeleceu uma norma para esse modelo de banco de dados. Como os
dados tinham uma forma limitada de independência física, a única garantia era que o sistema deveria recuperar os dados
para as aplicações como se eles estivessem armazenados na maneira indicada nos esquemas.
Concorrência e segurança foram definidas, pelos geradores de relatórios da CODASYL, como dois aspectos chaves dos
sistemas gerenciadores de dados. Para cada um desses aspectos foram definidas sintaxes. O mecanismo de segurança
fornecia uma facilidade em que parte do banco de dados (ou área) pudesse ser bloqueada para prevenir acessos simultâneos,
quando necessário. A sintaxe da segurança permitia que uma senha fosse associada a cada objeto descrito no esquema.
Ao contrário do modelo hierárquico, o modelo em rede possibilita acesso a qualquer nó da rede sem passar pela raiz. O
CAIDMS da Computer Associates é o sistema comercial mais divulgado do modelo em rede. O diagrama para representar
os conceitos do modelo em redes consiste em dois componentes básicos: Caixas, que correspondem aos registros, e
Linhas, que correspondem às associações. A Figura 2.3 ilustra um exemplo de diagrama do modelo em rede.
Figura 2.3. Diagrama Esquemático da Estrutura de Dados Cliente-Conta Corrente
Cliente Conta
Nome Rua Cidade N
o
Conta Corrente Saldo
Cliente Conta
Pedro R231 Guará 61893 500,00
João R121 Brasília 51935 100,00
R_Link
R_Link
Fonte: Adaptado de Silberschatz (2006).
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
19
Introdução à Modelagem Conceitual Unidade I
O Modelo de Rede apresenta algumas restrições devido:
• forte dependência da implementação;
• necessidade de criação de registros artificiais para implementar relacionamentos muitos para muitos;
• alta complexidade das consultas, pois o programador é forçado a pensar em termos de links e como percorrê-
los para obter as informações necessárias (manipulação de dados navegacional).
1.2.3. Modelo de Dados Relacional
O modelo relacional surgiu devido às necessidades de aumentar a independência de dados nos sistemas gerenciadores de
banco de dados; de prover um conjunto de funções apoiadas em álgebra relacional para armazenamento e recuperação de
dados, de permitir o processamento ad hoc1. Esse modelo, tendo por base a teoria dos conjuntos e a álgebra relacional,
foi resultado de um estudo teórico realizado por CODD[1]2.
Esse modelo foi o que revelou ser o mais flexível e adequado ao solucionar os vários problemas que se colocam no
nível da concepção e implementação da base de dados. Sua estrutura fundamental é a relação (tabela). Uma relação é
constituída por um ou mais atributos (campos) que traduzem o tipo de dados a armazenar. Tupla (registro) é o nome dado
a cada instância do esquema (linha).
O modelo relacional não tem caminhos pré-definidos para se fazer acesso aos dados como nos modelos que o precederam
e implementa estruturas de dados, organizadas em relações.
Figura 2.4. Diagrama de Estrutura Relacional Cliente-Conta Corrente
Cód_Cliente Nome Rua Cidade
1 João R121 Brasília
2 Pedro R231 Guará
Cód_Cliente N
o
Conta Corrente
1 61893
2 51935
N
o
Conta Corrente Saldo
61893 500,00
51935 100,00
Cód_Cliente Nome Rua Cidade
Cód_Cliente N
o
Conta Corrente
N
o
Conta Corrente Saldo
Fonte: Adaptado de Silberschatz (2006).
Algumas restrições devem ser impostas para que se trabalhe com essas tabelas e evitar aspectos indesejáveis como: repetição
de informação, incapacidade de representar parte da informação e perda de informação. Essas restrições são: integridade
referencial, chaves e integridade de junções de relações. A Figura 2.4 traz exemplos de tabelas sob o modelo relacional.
1.2.4. Modelo de Dados Orientado a Objetos
Em meados de 1980, começaram a se tornar comercialmente viáveis os bancos de dados orientados a objeto. Seu
surgimento foi motivado em função dos limites de armazenamento e representação semântica impostas no modelo
relacional. Os sistemas de informações geográficas (SIG), os sistemas CAD e CAM, que são mais facilmente construídos
usando tipos complexos de dados, são alguns dos exemplos que podem ser citados.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
20
Introdução à Modelagem Conceitual Unidade I
Uma característica das linguagens de programação orientadas a objetos é a habilidade para criar os tipos de dados
necessários. Contudo, esses sistemas necessitam guardar representações das estruturas de dados que utilizam no
armazenamento permanente.
O ODMG (Object Database Management Group) foi quem criou a estrutura padrão para os bancos de dados orientados a
objetos. Esse grupo é formado por representantes dos principais fabricantes desses bancos disponíveis comercialmente.
Os membros do grupo têm o compromisso de incorporar o padrão em seus produtos.
Modelo Orientado a Objetos é um termo usado para documentar o padrão que contém a descrição geral das facilidades
de um conjunto de linguagens de programação orientadas a objetos e a biblioteca de classes que pode formar a base para
o Sistema de Banco de Dados. Algumas das falhas perceptíveis do modelo relacional pareceram ter sido solucionadas
quando os bancos de dados orientados a objetos foram introduzidos e acreditava-se que tais bancos de dados ganhariam
grande parcela do mercado.
Acredita-se que nos dias atuais, enquanto os sistemas relacionais continuarão a sustentar os negócios tradicionais, onde
as estruturas de dados baseadas em relações são suficientes, os Bancos de Dados Orientados a Objetos serão usados
em aplicações especializadas.
O diagrama de classes UML serve geralmente como o esquema para o modelo de dados orientado a objetos. Observe o
exemplo da Figura 2.5. e compare as diferenças com o modelo anterior.
Figura 2.5. Diagrama UML Cliente-Conta Corrente
Cliente
Nome: String
Rua: String
Cidade: String
Conta
N
o
Conta Corrente: Inteiro
Saldo: Real
1..* 1..*
Fonte: Adaptado de Silberschatz (2006).
1.2.5. Modelo de Dados para Sistemas Objeto-Relacionais
Os sistemas relacionais convencionais têm dificuldade de representar e manipular dados complexos, visando ser mais
representativos em semântica e construções de modelagens; com isso, a área de atuação dos sistemas Objeto-Relacional
tenta suprir essas dificuldades. A solução proposta é a adição de facilidades para manusear tais dados utilizando-se
das facilidades SQL (Structured Query Language) existentes. Para isso, foi necessário adicionar: extensões dos tipos
básicos no contexto SQL; representações para objetos complexos no contexto SQL; herança no contexto SQL e sistema
para produção de regras.
1.3. A Arquitetura Três Esquemas
O principal objetivo da arquitetura três esquemas é permitir a separação das aplicações do usuário do banco de dados
físico. Uma representação gráfica da arquitetura três esquemas é apresentada na Figura 2.6. Com base nessa arquitetura,
é possível classificar os esquemas:
• nível interno: ou esquema interno, que descreve a estrutura de armazenamento físico do banco de dados;
utiliza um modelo de dados e descreve detalhadamente os dados armazenados e os caminhos de acesso ao
banco de dados;
• nível conceitual: ou esquema conceitual, que descreve a estrutura do banco de dados como um todo; é uma
descrição global do banco de dados, que não fornece detalhes do modo como os dados estão fisicamente
armazenados;
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
21
Introdução à Modelagem Conceitual Unidade I
• nível externo: ou esquema de visão, que descreve as visões do banco de dados para um grupo de usuários;
cada visão descreve as porções do banco de dados às quais um grupo de usuários terá acesso.
1.4. Independência de Dados
Segundo Oppel (2004), é possível definir a independência de dados como a capacidade de se alterar um esquema em
um nível em um banco de dados sem ter que alterar um nível superior. É possível classificar a independência de dados
em dois tipos:
• independência de dados lógica: é a capacidade de alterar o esquema conceitual sem ter que alterar o
esquema externo ou as aplicações do usuário;
• independência de dados física: é a capacidade de alterar o esquema interno sem ter que alterar o esquema
conceitual, o esquema externo ou as aplicações do usuário.
Figura 2.6. Arquitetura Três Esquemas
Visão Externa 1 Visão Externa n
Usuários Finais
Esquema Conceitual
Esquema Interno
NÍVEL
EXTERNO
NÍVEL
CONCEITUAL
NÍVEL
INTERNO
Banco de Dados Armazenado
...
Mapeamento
Conceitual
Externo
Mapeamento
Conceitual
Externo
2. Linguagens de Banco de dados
Cada camada e/ou função de um banco de dados necessita de um tipo de linguagem específica, conforme podemos ver.
2.1. Linguagem de Definição de Dados
A Linguagem de Definição de Dados ou Data Definition Language (DDL) é a linguagem utilizada pelo DBA e pelos
projetistas de banco de dados para definir seus esquemas. O SGBD, por sua vez, possui um compilador para processar
descrições em DDL e construir a descrição do esquema armazenado no catálogo.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
22
Introdução à Modelagem Conceitual Unidade I
2.2. Linguagem de Manipulação de Dados
A Linguagem de Manipulação de Dados ou Data Manipulation Language (DML) é a linguagem pela qual os usuários
manipulam os dados em um SGBD. Manipulações comuns como recuperação, inserção, remoção e modificação de dados
são realizadas pela DML.
2.3. Linguagem de Definição de Armazenamento
Em situações onde a separação entre os níveis conceitual e interno de um SGBD é bem clara, utiliza-se a Linguagem
de Definição de Armazenamento ou Storage Definition Language (SDL) para a especificação do esquema interno,
sendo que a especificação do esquema conceitual fica por conta da DDL.
2.4. Linguagem de Definição de Visões
Sistemas de Banco de Dados que utilizam a arquitetura três esquemas necessitam de uma linguagem para a definição
de visões, a Linguagem de Definição de Visões ou Vision Definition Language (VDL).
3. O Ambiente de Sistemas de Banco de Dados
O Ambiente dos Sistemas de Banco de Dados diz respeito ao conjunto de elementos necessário para que ocorram as
transações relativas ao armazenamento, processamento e recuperação de dados, conforme representado pela Figura 2.7.
3.1. Componentes de um Sistema Gerenciador de Banco de Dados
3.1.1. Processamento de Consultas
O componente de processamento de consultas é composto pelos seguintes elementos:
• Compilador DML: é o elemento que traduz os comandos DML em instruções de baixo nível, entendidos pelo
componente de execução de consultas. Também é responsável pela otimização de solicitações do usuário.
• Pré-compilador para comandos DML inseridos em programas de aplicação: são os elementos que
convertem comandos DML em chamadas de procedimentos normais da linguagem hospedeira. Também
interagem com o compilador DML de modo a gerar o código apropriado.
• Interpretador DDL: é o elemento que interpreta os comandos DDL e os registra no dicionário de dados.
• Componente de execução de consultas: é o elemento que executa instruções de baixo nível geradas pelo
compilador DML.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
23
Introdução à Modelagem Conceitual Unidade I
Figura 2.7. Um ambiente de Sistema de Banco de Dados
G
e
r
e
n
c
i
a
d
o
r

d
e

M
e
m
ó
r
i
a
Usuários
Interface
Usuários
Navegadores
Usuários
Avançados
Administradores
de BD
Programadores de
Aplicações
Interface com
Aplicações
Programas de
Aplicações
Esquema de
Banco de Dados
Consultas
(Queries)
Programas de
Aplicações em
Código Objeto
Pré-compilador de
Comandos DML
Interpretador DDL Compilador DML
Componente
de Execução de
Consultas
Gerenciador de
Buffer
P
r
o
c
e
s
s
a
d
o
r

d
e

C
o
n
s
u
l
t
a
s
Gerenciador de
Arquivos
Gerenciador de
Transações
Arquivos de
Dados
Índices
Dicionário de
Dados
Dados
Estatísticos
Banco de
Dados
S
i
s
t
e
m
a

G
e
r
e
n
c
i
a
d
o
r

d
e

























B
a
n
c
o

d
e

D
a
d
o
s
A
m
b
i
e
n
t
e

d
o

S
i
s
t
e
m
a

G
e
r
e
n
c
i
a
d
o
r

d
e

B
a
n
d
o

d
e

D
a
d
o
s
Fonte: Adaptado de Silberschatz (2006).
3.1.2. Gerenciador de Memória
O componente Gerenciador de Memória é o responsável por traduzir os diversos comandos DML em comandos de baixo
nível de sistemas de arquivos, o que lhe confere especial importância uma vez que um dos principais objetivos de um
SGBD é simplificar e otimizar o acesso aos dados. Visto que esse componente é responsável por fazer a interface entre
o armazenamento de dados em um nível mais baixo e as consultas e programas de aplicações submetidos ao sistema, é
possível afirmar que o Gerenciador de Memória é um dos principais elementos de um SGBD.
O componente de gerenciamento de memória é composto pelos seguintes elementos:
• Gerenciamento de Autorizações e Integridade: são os elementos que testam o cumprimento das regras
de integridade e a permissão ao usuário no acesso ao dado.
• Gerenciamento de Transações: são os elementos responsáveis pela execução das transações.
• Administração de Buffer
1
: é o elemento responsável pela intermediação de dados do disco para a memória
principal e pela decisão de quais dados alocar em memória auxiliar.
• Administração de Arquivos: é o elemento que gerencia a alocação de espaço no armazenamento em disco
e as estruturas de dados usadas para representar essas informações armazenadas.
1 Unidade de armazenamento temporária (relativo a computador). Fonte: http://www.merriam-webster.com/dictionary
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
24
Introdução à Modelagem Conceitual Unidade I
3.1.3. Módulo Banco de Dados
O Módulo Banco de Dados não se limita apenas a armazenar dados, uma vez que também contém definições e descrições
sobre a estrutura que forma o Banco de Dados (metadados). Os metadados, por sua vez, contêm definições da estrutura
de cada arquivo, o tipo e formato de armazenamento de cada item de dados e as restrições dos dados. Todas essas
definições ficam armazenadas no Catálogo de Dados (dicionário de dados) do Banco de Dados e são utilizadas pelo SGBD.
O Módulo Banco de Dados é composto por:
• Arquivo de Dados: é o elemento que armazena os dados (o banco de dados propriamente dito).
• Dicionário de Dados: é o elemento que armazena os metadados.
• Índices: é o elemento estrutural que otimiza o acesso aos itens de dados.
• Estatística de Dados: é o elemento que armazena informações estatísticas relativas aos dados contidos
no banco de dados. Essas informações são usadas pelo processador de consultas para seleção de meios
eficientes para execução de consultas.
3.3. Arquiteturas de Banco de Dados
Os mainframes eram utilizados pelas primeiras arquiteturas para executar o processamento principal e de todas as funções
do sistema, incluindo os programas aplicativos, programas de interface com o usuário, bem como a funcionalidade dos
SGBDs. Essa é a razão pela qual a maioria dos usuários fazia acesso aos sistemas via terminais que não possuíam poder
de processamento, mas, somente a capacidade de visualização. Apenas as informações a serem visualizadas e os controles
eram enviados do mainframe para os terminais de visualização e todos os processamentos eram feitos remotamente,
conectados a ele por redes de comunicação.
Muitos usuários trocaram seus terminais por Computadores Pessoais (PC) e estações de trabalho devido à queda dos
preços do hardware. No começo, os SGBDs usavam esses computadores da mesma maneira que usavam os terminais.
O SGBD era centralizado e toda sua funcionalidade, execução de programas aplicativos e processamento da interface
do usuário eram executados em apenas uma máquina.
Os SGBDs, gradualmente, começaram a explorar a disponibilidade do poder de processamento no lado do usuário, o que
levou à arquitetura cliente-servidor. Essa arquitetura foi desenvolvida para dividir ambientes de computação onde um
grande número de PCs, estações de trabalho, servidores de arquivos, impressoras, servidores de banco de dados e outros
equipamentos são conectados juntos por uma rede.
A idéia era definir servidores especializados, tais como servidor de arquivos, que mantém os arquivos de máquinas clientes,
ou servidores de impressão que podem estar conectados a várias impressoras; assim, quando se desejar imprimir algo,
todas as requisições de impressão são enviadas a esse servidor. As máquinas clientes disponibilizam para o usuário as
interfaces apropriadas para utilizar esses servidores, bem como o poder de processamento para executar aplicações locais.
A arquitetura cliente-servidor se tornou muito popular por causa da facilidade de implementação dada à clara separação
das funcionalidades e dos servidores; pelo servidor ser inteligentemente utilizado porque as tarefas mais simples são
delegadas às máquinas-clientes mais baratas e também porque o usuário pode executar uma interface gráfica que lhe é
familiar, ao invés de usar a interface do servidor.
Aos SGBDs comerciais, foi incorporada a arquitetura cliente-servidor e diferentes técnicas foram propostas para se
implementar essa arquitetura, sendo que a mais adotada pelos Sistemas Gerenciadores de Banco de Dados Relacionais
(SGBDRs) comerciais é a inclusão da funcionalidade de um SGBD centralizado no lado do servidor. Permanecem no
servidor de consulta ou servidor de transação as consultas e a funcionalidade transacional. É assim que um servidor
SQL é fornecido aos clientes.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
25
Introdução à Modelagem Conceitual Unidade I
Os clientes têm que formular suas consultas SQL, prover a interface do usuário e as funções de interface usando uma
linguagem de programação. Podem também se referir a um dicionário de dados, que inclui informações sobre a distribuição
dos dados em vários servidores SQL, bem como sobre os módulos para a decomposição de uma consulta global em um
número de consultas locais que podem ser executadas em vários sítios.
O servidor SQL também é chamado de back-end machine e o cliente de front-end machine. Como SQL provê uma linguagem
padrão para o SGBDRs, esta criou o ponto de divisão lógica entre o cliente e o servidor.
Atualmente, existem várias tendências para arquitetura de Banco de Dados, nas mais diversas direções.
As principais arquiteturas de SGBDs são:
• Plataformas centralizadas: nessa arquitetura existe um computador com grande capacidade de
processamento, sendo esse o hospedeiro do SGBD e emulador para os vários aplicativos. Sua principal
vantagem é a de permitir que muitos usuários manipulem grande volume de dados e sua principal desvantagem
está no seu alto custo, pois exige ambiente especial para mainframes e soluções centralizadas.
• Sistemas de Computador Pessoal: fazem seus processamentos sozinhos e, com isso, trabalham em sistema
stand-alone. No começo esse processamento era bastante limitado, porém, com a evolução do hardware,
tem-se hoje PCs com grande capacidade de processamento. Utilizam o padrão Xbase e, em se tratando de
SGBDs, funcionam como hospedeiros e terminais. Desta forma, possuem um único aplicativo a ser executado
na máquina e sua principal vantagem é a simplicidade.
• Banco de Dados Cliente-Servidor: nessa arquitetura, o cliente (front_end) executa as tarefas do aplicativo
fornecendo a interface do usuário (tela e processamento de entrada e saída). O servidor (back_end)
executa as consultas no DBMS e retorna os resultados ao cliente. Embora sendo uma arquitetura bastante
popular, são necessárias soluções sofisticadas de software que possibilitem: o tratamento de transações,
as confirmações de transações (commits), desfazer transações (rollbacks), linguagens de consultas (stored
procedures) e gatilhos (triggers). A principal vantagem dessa arquitetura é a divisão do processamento entre
dois sistemas, o que reduz o tráfego de dados na rede. (Ver Figura 2.8)
• Banco de Dados Distribuídos (N camadas): como se pode observar na Figura 2.9, a informação, nessa
arquitetura, está distribuída em diversos servidores. Cada servidor atua como no sistema cliente-servidor,
porém as consultas oriundas dos aplicativos são feitas para qualquer servidor indistintamente. Caso a
informação solicitada seja mantida por outro servidor ou servidores, o sistema encarrega-se de obter a
informação necessária, de maneira transparente para o aplicativo, que passa a atuar consultando a rede,
independente de conhecer seus servidores. As bases de dados corporativas, em que o volume de informação
é muito grande e, por isso, deve ser distribuído em diversos servidores são exemplos típicos. Porém, não é
dependente de aspectos lógicos de carga de acesso aos dados, ou de base de dados fracamente acopladas, em
que uma informação solicitada vai sendo coletada numa propagação da consulta numa cadeia de servidores.
A existência de diversos programas aplicativos consultando a rede para acessar os dados necessários é a
característica básica, porém, sem o conhecimento explícito de quais servidores dispõem desses dados.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
26
Introdução à Modelagem Conceitual Unidade I
Figura 2.8. Arquitetura Cliente-Servidor
Fonte: Produzido pelo autor.
Figura 2.9. Arquitetura Distribuída N Camadas
Fonte: Adaptado de Silberschatz (2006)
4. Classificação dos SGBDs
O principal critério utilizado para classificar um SGBD é o modelo de dados no qual é baseado. A grande maioria dos
SGBDs atuais são baseados no modelo relacional, alguns em modelos conceituais e outros em modelos orientados a
objetos. Outras classificações possíveis.
• Quanto aos usuários: um SGBD pode ser monousuário, comumente utilizado em computadores pessoais ou
multi-usuários, utilizado em estações de trabalho, minicomputadores e máquinas de grande porte.
• Quanto à localização: um SGBD pode ser localizado ou distribuído; se ele for localizado, então todos os
dados estarão em uma só máquina (ou em um único disco); se distribuído, os dados estarão distribuídos por
diversas máquinas (ou diversos discos).
• Quanto ao ambiente: ambiente homogêneo é o ambiente composto por um único SGBD e um ambiente
heterogêneo é o ambiente composto por diferentes SGBDs.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
27
Introdução à Modelagem Conceitual Unidade I
5. Exemplos de Sistemas Gerenciadores de Banco de Dados
Existem, atualmente no mercado, vários aplicativos que exercem a função de Sistemas Gerenciadores de Banco de Dados.
A seguir, apresentamos alguns exemplos.
• dBASE: é um aplicativo lançado pela Ashton-Tate e posteriormente adquirido pela Borland. Teve versões
para DOS e Windows, trabalhava com gerenciamento de arquivos planos baseados em listas invertidas e
possuía uma linguagem de programação própria para desenvolvimento de aplicações. A partir da versão 7, os
direitos foram vendidos pela Borland.
• Paradox: teve versões para DOS e hoje possui apenas versões para Windows. Possui ambiente integrado de
desenvolvimento para criação de aplicativos e seus direitos de produção foram vendidos para a Corel.
• DataFlex: teve versões para DOS e Windows e é popular para ambiente Unix. Hoje é comercializado com o
nome de Visual Data Flex e possui ambiente integrado para o desenvolvimento de aplicações.
• FoxBase/FoxPro: é um aplicativo concorrente do dBase, com total compatibilidade em termos de arquivos
e programas-fontes. Possui recursos adicionais como a capacidade de pré-compilação dos códigos-fontes
para melhorar o desempenho. Hoje, se chama Visual FoxPro após a aquisição pela Microsoft da Fox Software
(produtora original).
• Access: é um aplicativo que, por possuir ambiente integrado, permite a criação e gerenciamento do banco
de dados, desenvolvimento de aplicações e geração de relatórios. Sua linguagem de programação deriva do
Visual Basic. Para microcomputadores do ambiente Windows é padrão em banco de dados.
• Oracle: é o primeiro em Banco de Dados Corporativos (cliente/servidor) possuindo grande variedade de
distribuições (para Macintosh, Windows, Linux, FreeBSD, Unix) e para computadores de grande porte. É
padrão SQL com uma linguagem própria para desenvolvimento de aplicações.
• Interbase: teve uma versão liberada como Open Source e foi incluído, pela Borland, nas suas ferramentas de
desenvolvimento (Delphi, C++Builder, JBuider).
• MS-SQL Server: as versões atuais são independentes e operam exclusivamente sobre Windows. Foi
produzido pela Microsoft. Inicialmente era uma versão especial do Sybase.
• Sybase SQL Anywhere: as aplicações para esse banco de dados são desenvolvidas com o PowerBuilder. No
mercado, seu concorrente corporativo é o Oracle.
• MySQL: além de gratuito, possui versões para Windows, Solaris, Unix, FreeBSD, Linux. Usado principalmente
para desenvolvimento WEB como servidor de dados para comércio eletrônico.
• PostgreSQL: além de ser gratuito, tem boa aceitação. Foi concebido para rodar em Linux e possui versões
para Windows. É, principalmente, usado para comércio eletrônico, juntamente com a linguagem PHP.
• Informix: aplicativo comercializado pela IBM. Possui boa escalabilidade e desempenho.
• BD2: aplicativo produzido pela IBM, nasceu nos ambientes de grande porte, sendo posteriormente portado
para plataformas mais simples (microcomputadores).
• Firebird: aplicativo nascido de uma iniciativa da Borland em abrir o código do InterBase 6. Este sistema é
open source e esbanja versatilidade e robustez. Possui recursos de trigger, store procedures e transações
concorrentes.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
28
Introdução à Modelagem Conceitual Unidade I
Capítulo 3 – Modelagem de Dados Utilizando o MER
Uma entidade dever ter atributos que necessitam ser conhecidos
do ponto de vista dos negócios ou então não é uma entidade no
escopo dos requisitos do negócio.
1. O Modelo Entidade-Relacionamento (MER)
O Modelo Entidade-Relacionamento (MER) foi definido por Peter Chen,
,
em 1976, e teve como base a teoria relacional
criada por E.F.Codd (1970). Segundo Chen, a visão de uma dada realidade baseia-se no relacionamento entre entidades,
que retratam os fatos que governam essa mesma realidade, e que cada um (entidade ou relacionamento) pode possuir
atributos (qualificadores dessa realidade).
É um modelo de dados conceitual de alto nível, cujos conceitos foram projetados para estar o mais próximo possível da
visão que o usuário tem dos dados, não se preocupando em representar como esses dados estarão realmente armazenados.
Baseia-se na percepção de um mundo real que consiste em uma coleção de objetos básicos, denominados entidades, e
de relações entre esses objetos.
O MER é utilizado principalmente durante o processo de projeto de banco de dados e é, atualmente, a técnica mais
difundida, chegando a confundir-se com a própria modelagem de dados.
A Figura 3.1 faz uma descrição simplificada do processo de projeto de um banco de dados.
1.1. Características do MER
O modelo ER apresenta as seguintes características.
• Expressividade: suporta relacionamentos n-ários; inclui os três mecanismos de abstração: classificação,
agregação e generalização.
• Simplicidade: possui uma riqueza de conceitos e com isso se torna uma poderosa ferramenta para a
descrição da realidade. Não é um modelo muito simples, especialmente no que diz respeito aos conceitos de
cardinalidade, cobertura de generalização e identificação. Uma solução é produzir diagramas ER em diferentes
níveis de detalhe.
• Minimalidade: nenhum conceito do modelo pode ser descrito em termos dos demais, com exceção dos
atributos compostos. O fato de a mesma realidade poder ser modelada de diferentes maneiras não invalida a
minimalidade do modelo.
• Formalidade: possui o necessário grau de formalidade, uma vez que cada um de seus conceitos possui uma
interpretação única, precisa e bem-definida.
• Representação gráfica: todos os seus conceitos possuem um símbolo gráfico associado, por isso, é um
modelo graficamente completo. Os diagramas ER são fáceis de serem entendidos pelos usuários.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
29
Introdução à Modelagem Conceitual Unidade I
2. Uma aplicação
A Figura 3.1 descreve uma base de dados COMPANHIA, que será utilizada para ilustrar o processo de projeto de base
de dados. São listados os requisitos da base de dados e criado o seu esquema conceitual passo a passo ao mesmo tempo
em que são introduzidos os conceitos de modelagem usando o MER.
A base de dados COMPANHIA armazena os dados dos empregados, departamentos e projetos. Supõe-se que após a
Obtenção e Análise dos Requisitos, os projetistas da base de dados produziram a seguinte descrição do minimundo –
parte da companhia a ser representada na base de dados.
• A companhia é organizada em departamentos. Cada departamento tem um nome, um número e um empregado
que o gerencia. Armazena-se a data de início em que o empregado começou a gerenciar o departamento. Um
departamento pode ter diversas localizações.
• Um departamento controla inúmeros projetos, sendo que cada um tem um nome, um número e uma localização.
• Do empregado armazena-se o nome, número do seguro social, endereço, salário, sexo e a data de nascimento.
Todo empregado é associado a um departamento, mas pode trabalhar em diversos projetos, que não são
necessariamente controlados pelo mesmo departamento. Armazena-se, também, o número de horas que o
empregado trabalha em cada projeto. Mantém-se, ainda, a indicação do supervisor direto de cada projeto.
• Os dependentes de cada empregado são armazenados com o propósito de garantir os benefícios do seguro.
Para cada dependente será armazenado o nome, sexo, data de nascimento e o relacionamento com o
empregado.
Figura 3.1: Esquematização da Modelagem de Dados usando o MER
Obtenção e Análise Requisitos
Projeto Conceitual
Projeto Físico
Mini-Mundo
Requisitos da Base de Dados
Modelo Conceitual (Alto-Nível)
Esquema Conceitual (SGBD específico)
Esquema Interno
Banco de Dados
C
o
m
u
m

a

t
o
d
o
s

o
s

t
i
p
o
s

d
e

S
G
B
D
C
o
n
f
o
r
m
e

o

S
G
B
D

Mapeamento do Modelo de Dados
Fonte: Adaptado de Silberschatz (2006).
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
30
Introdução à Modelagem Conceitual Unidade I
3. Entidades e Atributos
O objeto básico tratado pelo modelo ER é a entidade, que pode ser definida como um objeto do mundo real, concreto ou
abstrato e que possui existência independente.
Cada entidade possui um conjunto particular de propriedades que a descreve, denominado atributos. Para cada atributo
existe um conjunto de valores permitidos, que é chamado de domínio desse atributo. Um atributo pode ser dividido em
diversas partes menores com significado independente entre si, recebendo o nome de atributo composto. Um atributo
que não pode ser subdividido é chamado de atributo simples ou atômico.
O atributo que pode assumir apenas um determinado valor em uma determinada instância é denominado atributo
simplesmente valorado, enquanto que um atributo que pode assumir diversos valores em uma mesma instância é denominado
multivalorado. Um atributo que é gerado a partir de outro é chamado de atributo derivado.
4. Tipos Entidade, Conjunto de Valores, Atributo Chave
Um banco de dados costuma conter grupos de entidades que são similares, possuindo os mesmos atributos, porém, cada
entidade conta com seus próprios valores para cada atributo. Esse conjunto de entidades similares forma tipo entidade.
Cada tipo entidade é identificado por seu nome e pelo conjunto de atributos que definem suas propriedades. A descrição
do tipo entidade é chamada de esquema do tipo entidade, onde são especificados o nome do tipo entidade, o nome
de cada um de seus atributos e qualquer restrição que incida sobre as entidades.
5. Relacionamentos
5.1. Tipos de Relacionamento
Um tipo relacionamento R entre n entidades E
1
, E
2
, ..., E
n
é um conjunto de associações possíveis entre entidades desse
tipo. Em outras palavras, cada instância de relacionamento r
1
em R é uma associação de entidades. Isso significa que
essas entidades estão relacionadas de alguma forma no minimundo.
A Figura 3.2 mostra um exemplo entre dois tipos entidade (empregado e departamento) e o relacionamento entre eles
(trabalha para). Repare que para cada relacionamento participa apenas uma entidade de cada tipo entidade, porém, uma
entidade pode participar de mais de um relacionamento.
Figura 3.2. Exemplo de um Relacionamento Binário
R
1
R
2
R
3
R
4
R
5
R
6
Trabalha Para Empregado
E
1
E
2
E
3
E
4
E
5
E
6
Departamento
D
1
D
2
D
3
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
31
Introdução à Modelagem Conceitual Unidade I
5.2. Grau de um Relacionamento
O grau de um tipo relacionamento é o número de tipos entidade que participam do tipo relacionamento. No exemplo
da Figura 3.2, temos um relacionamento binário. O grau de um relacionamento é ilimitado, porém, a partir do grau 3, a
compreensão e a dificuldade de se desenvolver a relação corretamente se tornam extremamente complexas.
Um exemplo de um tipo de relacionamento ternário é Fornece para, ilustrado na Figura 3.3. Cada instância de
relacionamento R
1
associa três entidades – um fornecedor F, uma peça E e um projeto P – onde o fornecedor F fornece
a peça E para o projeto P. Podem existir tipos de relacionamento de qualquer grau, porém é mais freqüente encontrar o
tipo de relacionamento de grau dois.
5.3. Relacionamentos como Atributos
Algumas vezes é conveniente pensar em um relacionamento como um atributo. Considere o exemplo da Figura 3.2. Podemos
pensar departamento como sendo um atributo da entidade empregado, ou empregado, como um atributo multivalorado
da entidade departamento. Se uma entidade não possuir existência muito bem definida, talvez seja mais interessante
para a coesão do modelo lógico que ela seja representada como um atributo.
Figura 3.3. Exemplo de um Relacionamento Ternário
R
1
R
2
R
3
R
4
R
5
R
6
Fornecer para
Peças
E
1
E
2
E
3
E
4
E
5
E
6
Projeto
P
1
P
2
P
3
Fornecedor
F
1
F
2
5.4. Nomes de Papéis e Relacionamentos Recursivos
Cada tipo entidade que participa de um tipo relacionamento desempenha um papel particular no relacionamento. O nome do
papel representa o papel que uma entidade de um tipo entidade participante desempenha no relacionamento. No exemplo
da Figura 3.2, nós temos o papel empregado ou trabalhador para o tipo entidade EMPREGADO e o papel departamento
ou empregador para a entidade DEPARTAMENTO.
Nomes de papéis não são necessariamente importantes quando todas as entidades participantes desempenham papéis
diferentes. Algumas vezes, o papel torna-se essencial para distinguir o significado de cada participação. Isso é muito
comum em “relacionamentos recursivos”.
Um relacionamento recursivo é um relacionamento entre entidades do mesmo tipo entidade, conforme ilustrado na Figura
3.4.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
32
Introdução à Modelagem Conceitual Unidade I
Na Figura 3.4, temos um relacionamento entre o tipo entidade EMPREGADO, onde um empregado pode supervisionar
outro empregado e um empregado pode ser supervisionado por outro empregado.
Figura 3.4. Um Relacionamento Recursivo
Supervisiona
R
1
R
2
R
3
R
4
R
5
R
6
Empregado
E
1
E
2
E
3
E
4
E
5
E
6
Supervisiona
Supervisionando
6. Refinando o Projeto de Entidade-Relacionamento
6.1. Tipos Entidades Fracas
Em alguns casos, alguns tipos entidade podem não ter um atributo chave por si só. Isso implica que não poderemos distinguir
algumas entidades porque as combinações dos valores de seus atributos podem ser idênticas. Esses tipos entidade são
chamados entidades fracas. As entidades desse tipo precisam estar relacionadas com uma entidade pertencente ao
tipo entidade proprietária. Esse relacionamento é chamado de relacionamento identificador.
Na Figura 3.5, o tipo entidade DEPENDENTE é uma entidade fraca uma vez que não possui um método de identificar
uma entidade única. O EMPREGADO não é uma entidade fraca uma vez que possui um atributo para identificação
(atributo chave).
O número do CPF de um empregado pode identificar um único empregado, porém um dependente de 5 anos de idade não
possui necessariamente um documento como esse. Dessa forma, essa entidade é um tipo entidade fraca.
Figura 3.5. Exemplo de um Relacionamento com uma Entidade Fraca
Possui Dependente
R
1
R
2
R
3
Empregado
E
1
E
2
E
3
Dependente
D
1
D
2
D
3
Um tipo entidade fraca possui uma chave parcial que, juntamente com a chave primária da entidade proprietária,
forma uma chave primária composta.
No exemplo da Figura 3.5 a chave primária do EMPREGADO pode ser o CPF. A chave parcial do DEPENDENTE
pode ser o seu nome, pois dois irmãos não podem ter o mesmo nome. Desse modo, a chave primária desta entidade
fica sendo o CPF do pai ou da mãe mais o nome do dependente.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
33
Introdução à Modelagem Conceitual Unidade I
6.2. Atributos em Tipos de Relacionamentos
Os tipos de relacionamento também podem ter atributos da mesma maneira que os tipos de entidades. Exemplificando,
tomemos a situação representada pela Figura 3.6 e acrescentemos a necessidade de representar a data em que um
EMPREGADO começou a gerenciar um DEPARTAMENTO por meio de um atributo Data_Início para o tipo de
relacionamento GERÊNCIA.
Figura 3.6. Exemplo de um Relacionamento
Gerência
R
1
R
2
R
3
Departamento
D
1
D
2
D
3
Empregado
E
1
E
2
E
3
E
4
E
5
E
6
Nesse caso, é possível perceber que atributos de tipos de relacionamento 1:1 ou 1:N podem ser incluídos como atributos
de um dos tipos de entidades participantes. Assim, o atributo Data_Início para o tipo de relacionamento GERÊNCIA
pode ser um atributo tanto de EMPREGADO quanto de DEPARTAMENTO embora, conceitualmente, ele pertença
ao relacionamento GERÊNCIA. Isso ocorre porque GERÊNCIA é um relacionamento 1:1, uma vez que toda entidade
DEPARTAMENTO ou EMPREGADO participam em apenas uma instância de relacionamento e, dessa forma, o valor do
atributo Data_Início pode ser representado em qualquer uma das entidades participantes.
No caso de um tipo de relacionamento 1:N, um atributo de relacionamento pode somente ser colocado no tipo de
entidade que está do lado N do relacionamento. Isso pode ser visto na Figura 3.2, pois se o relacionamento TRABALHA-
PARA tiver um atributo Data_Início, indicando quando um empregado começou a trabalhar para um DEPARTAMENTO,
esse atributo pode ser colocado como atributo de EMPREGADO. Isso ocorre porque o relacionamento é 1:N de modo
que cada entidade EMPREGADO participa apenas uma única vez em uma instância de TRABALHA-PARA.
Uma vez que o valor de um atributo é determinado pela combinação das entidades participantes em uma instância de
relacionamento, e não apenas por uma das entidades, então o atributo deve ser especificado como um atributo de
relacionamento. Esse é o caso de atributos de tipos de relacionamentos M:N, porque as entidades dos tipos de entidades
participantes podem participar em inúmeras instâncias de relacionamento.
Exemplificando, tomemos a situação descrita na Figura 3.2 e acrescentemos a necessidade de incluir o atributo Horas_
Trabalhadas do relacionamento M:N TRABALHA-PARA. O número de horas que um empregado trabalha em um projeto
é determinado pela combinação empregado-projeto e não separadamente.
6.3. Modelo Entidade-Relacionamento Estendido (ERE)
Os conceitos do modelo Entidade-Relacionamento, discutidos anteriormente, são suficientes para representar logicamente
a maioria das aplicações de banco de dados. Porém, com o surgimento de novas aplicações, surgiu também a necessidade
de novas semânticas para a modelagem de informações mais complexas.
O modelo Entidade-Relacionamento Estendido (ERE) visa fornecer esta semântica para permitir a representação
de informações complexas. É importante frisar que, embora o modelo ERE trate classes e subclasses, ele não possui a
mesma semântica de um modelo orientado a objetos.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
34
Introdução à Modelagem Conceitual Unidade I
O modelo ERE engloba todos os conceitos do modelo E-R mais os conceitos de subclasse, superclasse, generalização,
especialização e o de herança de atributos.
6.3.1. Subclasses, Superclasses e Especializações
O primeiro conceito do modelo ERE, que será abordado, é o de subclasse de um tipo entidade.
Como visto anteriormente, um tipo entidade é utilizado para representar um conjunto de entidades do mesmo tipo. Em
muitos casos, um tipo entidade possui diversos subgrupos adicionais de entidades que são significativas e precisam ser
representadas explicitamente, devido ao seu significado, à aplicação de banco de dados. Considere o seguinte exemplo:
Para um banco de dados de uma empresa temos o tipo entidade empregado, o qual possui as seguintes características:
nome, RG, CPF, número funcional, endereço completo (rua, número, complemento, CEP, bairro, cidade), sexo, data de
nascimento e telefone (ddd e número); caso o(a) funcionário(a) seja um(a) engenheiro(a), então deseja-se armazenar
as seguintes informações: número do CREA e especialidade (Civil, Mecânico, Eletrônico); caso o(a) funcionário(a) seja
um(a) secretário(a), então se deseja armazenar as seguinte informações: qualificação (bi ou trilíngue) e os idiomas em
que possui fluência verbal e escrita.
Se as informações número do CREA, especialidade, tipo e idiomas forem representados diretamente no tipo entidade
empregado estaremos representando informações de um conjunto limitado de entidades empregado para os todos os
funcionários da empresa. Nesse caso, podemos criar duas subclasses do tipo entidade empregado: engenheiro e secretária,
as quais irão conter as informações acima citadas. Além disto, engenheiro e secretária podem ter relacionamentos
específicos.
Uma entidade não pode existir meramente como componente de uma subclasse. Antes de ser componente de uma
subclasse, uma entidade deve ser componente de uma superclasse. Isto leva ao conceito de herança de atributos; ou
seja, a subclasse herda todos os atributos da superclasse. Isso porque a entidade de subclasse representa as mesmas
características de uma mesma entidade da superclasse. Uma subclasse pode herdar atributos de superclasses diferentes.
Uma representação diagramática do exemplo mencionado é ilustrada na Figura 3.7.
Figura 3.7. Representação de Superclasse e Subclasses
Nome
N
o
Funcional
CPF
RG
Dt. Nascimento
Sexo
Endereço
Empregado
Função
d
Engenheiro Engenheiro
N
o
Registro
Especialização
Qualificação
Idiomas
6.3.2. Especialização
Especialização é o processo de definição de um conjunto de classes de um tipo entidade; esse tipo entidade é chamado
de superclasse da especialização. O conjunto de subclasses é formado com base em alguma característica que distinga
as entidades entre si.
No exemplo da Figura 3.7, temos uma especialização, que podemos chamar de função. Veja agora no exemplo da Figura
3.8, temos a entidade empregado e duas especializações.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
35
Introdução à Modelagem Conceitual Unidade I
Figura 3.8. Duas Especializações para Empregado: Função e Categoria Salarial
Engenheiro Horista Secretária Mensalista
Empregado
Função
Categoria
Salarial
d
d
Como visto anteriormente, uma subclasse pode ter relacionamentos específicos com outras entidades ou com a própria
entidade, que é a sua superclasse. Veja o exemplo da Figura 3.9.
Figura 3.9. Relacionamentos entre Subclasses e Entidades
d
Secretária
Empregado
Engenheiro
Projeto
É desenvolvido por
N
N
S
N
É liderado
Lidera
Participa
Função
O processo de especialização nos permite:
• definir um conjunto de subclasses de um tipo entidade;
• associar atributos específicos adicionais para cada subclasse;
• estabelecer tipos relacionamentos específicos entre subclasses e outros tipos entidades.
6.3.3. Generalização
A generalização pode ser pensada como um processo de abstração reverso ao da especialização, no qual são suprimidas
as diferenças entre diversos tipos entidades, identificando suas características comuns e generalizando essas entidades
em uma superclasse.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
36
Introdução à Modelagem Conceitual Unidade I
Figura 3.10. Tipos Entidades Engenheiro e Secretária
Figura 3.11. Generalização Empregado para os Tipos Entidades Engenheiro e Secretária
É importante destacar que existe diferença semântica entre a especialização e a generalização. Na especialização, podemos
notar que a ligação entre a superclasse e as subclasses é feita por meio de um traço simples, indicando participação
parcial por parte da superclasse. Analisando o exemplo da Figura 3.9, é observado que um empregado não é obrigado a
ser um engenheiro ou uma secretária. Na generalização, podemos notar que a ligação entre a superclasse e as subclasses
é feita por intermédio de um traço duplo, indicando participação total por parte da superclasse. Analisando o exemplo
da Figura 3.10, é observado que um empregado é obrigado a ser um engenheiro ou uma secretária.
A letra d dentro do círculo que especifica uma especialização ou uma generalização significa disjunção. Uma disjunção
em uma especialização ou generalização indica que uma entidade do tipo entidade que representa a superclasse pode
assumir apenas um papel dentro dela. Analisando o exemplo da Figura 3.11 temos duas especializações para a superclasse
Empregado, as quais são restringidas por meio de uma disjunção. Nesse caso, um empregado pode ser um engenheiro ou
uma secretária e ele pode ser horista ou mensalista.
Além da disjunção, podemos ter um overlap, representado pela letra o. No caso do “overlap”, uma entidade de uma
superclasse pode ser membro de mais que uma subclasse em uma especialização ou generalização. Analise a generalização
no exemplo da Figura 3.12. Suponha que uma peça fabricada em uma tornearia pode ser manufaturada ou torneada, ou
ainda, pode ter sido manufaturada e torneada.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
37
Introdução à Modelagem Conceitual Unidade I
Figura 3.12. Uma Generalização com “Overlap”
6.3.4. “Lattice” ou Múltipla Herança
Uma subclasse pode ser definida por meio de um “lattice”, ou múltipla herança, ou seja, ela pode ter diversas superclasses,
herdando características de todas. Tomemos como base a situação de que uma construtora possui diversos funcionários,
que podem ser engenheiros ou secretárias. Um funcionário pode também ser assalariado ou horista. Todo gerente de
departamento da construtora deve ser um engenheiro e assalariado.
O modelo lógico da expressão acima tem o seguinte formato (Figura 3.13):
Figura 3.13. Um “Lattice” com a Subclasse Gerente Compartilhada
Nesse caso, então, um gerente será um funcionário que, além de possuir as características próprias de Gerente, herdará
as características de Engenheiro e de Mensalista.
7. Diagrama Entidade-Relacionamento
O Diagrama Entidade-Relacionamento (DER) é composto por um conjunto de objetos gráficos que visa representar
todos os objetos do modelo Entidade Relacionamento, tais como entidades, atributos, atributos chaves, relacionamentos,
restrições estruturais etc.
O diagrama ER oferece uma visão lógica do banco de dados, fornecendo um conceito mais generalizado de como estão
estruturados os dados de um sistema.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
38
Introdução à Modelagem Conceitual Unidade I
7.1. Tipos de Notação do Modelo Entidade-Relacionamento
Várias formas de notação de um MER foram desenvolvidas. Entre elas podemos destacar:
• ER – Peter Chen
• UML – OMG (Grady, Booch, Rumbaugh)
• IE (Information Engineering) – J. Martin
• IDEF1X (US Federal Governament)
Apesar de todas se destinarem, em suma, à mesma finalidade, a notação mais utilizada ainda é a ER, proposta por Peter
Chen.
Os elementos gráficos que compõem o Diagrama Entidade-Relacionamento (DER), proposto por Chen (1976), são:
• Retângulos: conjuntos de entidades.
• Linhas duplas: conjuntos de entidades fracas.
• Elipses: atributos. Os atributos da chave primária são sublinhados.
• Losangos: conjuntos de relacionamentos. Linhas duplas representam conjuntos de relacionamentos envolvidos
com entidades fracas.
• Linhas: unem atributos aos conjuntos de entidades e esses aos conjuntos de relacionamentos.
• Linhas direcionadas: a seta indica a cardinalidade um.
• Elipses duplas: atributos multivalorados. Linhas duplas indicam participação total de uma entidade em um
conjunto de relacionamentos.
A Figura 3.14 apresenta os objetos que compõem o diagrama E-R.
Apresentamos, na Figura 3.15, um DER para o esquema da base de dados COMPANHIA.
Mapeando a descrição apresentada na Figura 3.14, teremos:
• Os tipos de entidades tais como EMPREGADO, DEPARTAMENTO e PROJETO são mostrados em retângulos.
• Os tipos de relacionamentos tais como TRABALHA-PARA, GERENCIA, CONTROLA e TRABALHA-EM são
mostrados em losangos interligados a tipos de entidades participantes.
• Os atributos são mostrados em elipses conectadas a tipos de entidades ou relacionamentos.
• Os componentes de um atributo composto são também representados em elipses, porém conectados ao
atributo ao qual eles pertencem (atributo Nome de EMPREGADO).
• Os atributos multivalorados são denotados em elipses com linhas duplas (atributo Localização de
DEPARTAMENTO).
• Os atributos-chaves são representados de forma sublinhada.
• Os atributos derivados são representados em elipses com linhas tracejadas (atributo Número De Empregados
de DEPARTAMENTO).
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
39
Introdução à Modelagem Conceitual Unidade I
• Os tipos de entidades-fracas são distinguidos por retângulos com linhas duplas e os relacionamentos de
identificação, por losangos com linhas duplas (tipo de entidade-fraca DEPENDENTE e tipo de relacionamento
de identificação DEPENDENTE-DE).
Figura 3.14. Objetos que Compõem o Diagrama ER
• A chave-parcial de um tipo de entidade-fraca é sublinhada com linha tracejada.
• São mostradas as razões de cardinalidade para cada tipo de relacionamento binário. A razão de cardinalidade
de DEPARTAMENTO: EMPREGADO em GERÊNCIA é 1:1, para DEPARTAMENTO: EMPREGADO em
TRABALHA-PARA é 1:N e M:N para TRABALHA em.
• As restrições de participação parcial são especificadas por linhas simples. As linhas paralelas denotam
participação total (dependência existencial).
• São apresentados os nomes de papéis para o tipo de relacionamento SUPERVISIONA porque o tipo de entidade
EMPREGADO ocupa dois papéis nesse relacionamento.
Na Figura 3.15 é apresentado o mesmo esquema da Figura 3.16, porém com a utilização da notação alternativa para
ilustrar as restrições estruturais de tipos de relacionamentos.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
40
Introdução à Modelagem Conceitual Unidade I
Figura 3.15. – DER para o Esquema Companhia
Figura 3.16. – DER para o Esquema Companhia com Notação Alternativa
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
41
Capítulo 4 – Modelo de Dados Relacional
Hoje em dia o termo banco de dados é bastante popular em diversas
áreas de atuação. Com o aumento da utilização de computadores na
manipulação de dados que envolvem diversas aplicações, os bancos
de dados estão sendo desenvolvidos e aplicados nas diferentes
áreas que envolvem o comércio, a indústria e a pesquisa acadêmica
entre outras.
1. Introdução
Segundo Silberschatz (2006), Modelo de Dados é uma coleção de ferramentas conceituais para descrever dados, relações
de dados, semântica de dados e restrições de consistência, constituindo-se em uma maneira de descrever o projeto de
um banco de dados nos seus vários níveis de abstração.
As bases do modelo relacional foram lançadas por Edgar Codd, nos anos 1970, e começou a ser realmente utilizado
nas empresas a partir de 1987, por meio do SGBDs, tendo como finalidade representar os dados como uma coleção de
relações, onde cada relação é representada por uma tabela. O conceito principal vem da teoria dos conjuntos (álgebra
relacional) atrelado à idéia de que não é relevante ao usuário saber onde os dados estão nem como os dados estão.
Quando uma relação é pensada como uma tabela de valores, cada linha nessa tabela representa uma coleção de dados
relacionados. Esses valores podem ser interpretados como fatos descrevendo uma instância de uma entidade ou de um
relacionamento. O nome da tabela e das colunas são utilizados para facilitar a interpretação dos valores armazenados
em cada uma de suas linhas. Todos os valores em uma coluna são necessariamente do mesmo tipo.
Na terminologia do modelo relacional temos:
• cada tabela é chamada de relação;
• cada linha de uma tabela é chamada de tupla;
• cada coluna é denominada atributo;
• o tipo de dado que descreve cada coluna é chamado de domínio;
• o grau da relação é o número do atributos da relação.
Unidade II
Sistemas de Banco de Dados:
conceitos e arquiteturas
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
42
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Segundo Takai (2005), quando uma relação é vista como uma tabela de valores, cada linha representa uma coleção de
valores relacionados. Esses valores podem ser interpretados como um fato que descreve uma entidade ou uma instância
de relacionamento. O nome da tabela e os nomes das colunas são usados para ajudar a interpretar o significado dos
valores em cada linha da tabela.
Exemplificando, na Figura 4.1, a primeira tabela é chamada ESTUDANTE porque cada linha representa o fato sobre uma
particular entidade estudante. Os nomes das colunas – Nome, Número, Classe, Departamento – especificam como
interpretar os valores em cada linha, baseando-se nas colunas em que cada um se encontra. Todos os valores de uma
coluna são, normalmente, do mesmo tipo.
Figura 4.1. Exemplo de uma base de dados relacional
ESTUDANTE Nome Matrícula Classe Departamento
José 3217 1 DCT
Ana Maria 2325 2 DCT
Carla 4112 1 ENG
CURSO Nome Código Créditos Departamento
Banco de Dados I BD1322 4 DCT
Redes Neurais RN1132 4 DCT
Banco de Dados II BD1323 4 DCT
Cáculo I CA1011 4 ENG
SEÇÃO Número Curso Semestre Ano Professor
11 RN1132 1 2007 Antônio
13 BD1322 1 2007 Pedro
13 BD1323 2 2007 Angélica
10 CA1011 1 2006 Pedro
Tomemos como exemplo de uma relação esquema R de grau 4, que descreve estudantes universitários:
R
ESTUDANTE
(Nome, Número, Classe, Departamento)
Nessa relação-esquema, ESTUDANTE é o nome da relação esquema, que tem 4 atributos. Podemos especificar alguns
domínios para cada atributo da relação ESTUDANTE:
dom(Nome)=Nomes
dom(Matrícula)=Número da matrícula dos alunos
dom(Classe)=Número de identificação das turmas
dom(Departamento)=Código relativo ao departamento a que os cursos estão vinculados
Uma relação r
1
da relação esquema R(A
1
, A
2
, ..., A
n
), também denotada por r(R), é um conjunto de tuplas r={ t
1
, t
2
, ...,
t
m
}. Cada tupla t é uma lista ordenada de n valores t=<v
1
, v
2
, ..., v
n
>, onde cada valor v
i
, 1 ≤ i ≤ n, é um elemento
do dom(A
i
) ou um valor especial null. São utilizados, com freqüência, os termos intenção da relação para o esquema R e
extensão da relação para a instância r(R).
1.1. Atributos-chave de uma relação
Uma relação é definida como um conjunto de tuplas. Pela definição, todos os elementos de um conjunto são distintos.
Assim, todas as tuplas de uma relação também são distintas. Isso significa que nenhuma tupla pode ter a mesma
1 Também chamada de instância de relação
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
43
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
combinação de valores para todos os seus atributos. Normalmente, existem subconjuntos de atributos de uma relação
esquema R com a propriedade de que nenhuma tupla de uma relação r de R tenha a mesma combinação de valores para
esses atributos. Suponha que esse subconjunto seja denotado por SC; então, para quaisquer tuplas t
1
e t
2
em r de R,
deve valer a regra:
t
1
[SC] ≠ t
2
[SC]
Assim, SC é chamada Super-Chave da relação esquema R. Toda relação tem ao menos uma Super-Chave, que é o
conjunto de todos os seus atributos. Uma chave C, de uma relação esquema R, é uma Super-Chave de R com a propriedade
adicional de não se poder remover qualquer atributo A de C e continuar a ser Super-Chave de R. Assim, uma chave é
uma Super-Chave mínima; uma super-chave da qual não se pode remover qualquer atributo.
Por exemplo, considere a relação ESTUDANTE da Figura 4.1. O conjunto de atributos {Número} é uma Super-Chave
de ESTUDANTE, porque se sabe que nenhum estudante irá ter o mesmo número de matrícula, e também é uma chave,
pois não se pode remover nenhum atributo. Qualquer conjunto de atributos que inclua Número - por exemplo, {Número,
Nome, Anos} - será uma Super-Chave.
No entanto, o conjunto {Número, Nome, Departamento} não é uma chave de ESTUDANTE porque, removendo Nome
ou Anos, ou ambos, o conjunto resultante será ainda uma Super-Chave.
A chave deve ser determinada pelo significado dos atributos na relação esquema e deve ser invariante ao tempo. Por
exemplo, o atributo Nome da relação ESTUDANTE não pode ser indicado como chave, uma vez que nada garante a não
ocorrência de homônimos. Em geral, uma relação esquema pode ter mais que uma chave. Nestes casos, cada chave é
chamada chave-candidata. Por exemplo, o esquema da relação ESTUDANTE poderia ter um atributo adicional Código,
para indicar o código interno de estudantes na escola. Assim, o esquema teria duas chaves candidatas: Número e
Código. É comum designar uma das chaves-candidatas como a Chave-Primária da relação. A indicação no modelo de
qual Chave-Candidata é a Chave-Primária é efetuada sublinhando-se os atributos que formam a Chave-Candidata
escolhida. Quando uma relação esquema tem muitas Chaves-Candidatas, a escolha da Chave-Primária é arbitrária.
No entanto, é sempre melhor escolher a Chave-Primária com o menor número de atributos.
Dicas
• O sinônimo é um nome alternativo para a entidade. São muito utilizados quando dois grupos de usuários
têm diferentes nomes para o mesmo objeto significante.
2. Restrições do Modelo Relacional
2.1. Restrições em Tipos Relacionamentos
Em geral, os tipos relacionamentos sofrem certas restrições que limitam as possíveis combinações das entidades
participantes. Essas restrições são derivadas de restrições impostas pelo estado dessas entidades no minimundo.
A Figura 3.6 representa a situação de que um empregado pode gerenciar apenas um departamento, enquanto que um
departamento pode ser gerenciado por apenas um empregado.
Esse tipo de restrição é chamado de cardinalidade. A cardinalidade indica o número de relacionamentos dos quais uma
entidade pode participar.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
44
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
A cardinalidade apresenta as seguintes possibilidades:
• um para um (1:1);
• um para vários (1:N);
• vários para vários (M:N).
No exemplo da Figura 3.6, a cardinalidade é 1:1, pois cada entidade EMPREGADO pode gerenciar apenas um
DEPARTAMENTO e um DEPARTAMENTO pode ser gerenciado por apenas um EMPREGADO.
No exemplo da figura 3.3, no relacionamento FORNECEDOR - Fornece Para - PROJETO, o relacionamento é M:N, pois
um fornecedor pode fornecer várias peças para vários projetos.
Uma restrição muito importante é a participação. A participação define a existência de uma entidade por intermédio do
relacionamento, podendo ser parcial ou total.
No exemplo da Figura 3.6, a participação do empregado é parcial, pois nem todo EMPREGADO gerencia um
DEPARTAMENTO, porém a participação do departamento nesse relacionamento é total, pois todo DEPARTAMENTO
necessita ser gerenciado por um EMPREGADO. Dessa forma, todas as entidades do tipo entidade DEPARTAMENTO
precisam participar do relacionamento, mas nem todas as entidade do tipo entidade EMPREGADO precisam
participar do relacionamento.
Na Figura 3.2, ambas as participações são totais, pois todo EMPREGADO precisa trabalhar em um DEPARTAMENTO
e todo DEPARTAMENTO tem que ter EMPREGADOS trabalhando nele. Essas restrições são chamadas de restrições
estruturais.
2.2. Restrições de Integridade
As chaves-candidatas de cada relação esquema são especificadas pelas restrições de chave. Essas chaves-candidatas
possuem valores que devem ser únicos para todas as tuplas de quaisquer instâncias da relação esquema.
Além da restrição de chave, existem dois outros tipos de restrições no modelo relacional: a integridade de entidade e a
integridade referencial.
Na restrição de integridade de entidade nenhum valor da chave-primária pode ser nulo, pois o valor de uma chave-
primária é utilizado para identificar tuplas em uma relação. Por exemplo, se duas ou mais tuplas tiverem o valor null para
a chave primária, não haverá como diferenciar uma tupla da outra.
As restrições de chave e de integridade de entidade aplicam-se apenas a relações individuais.
A restrição de integridade referencial é usada para manter a consistência entre tuplas de duas relações. Informalmente,
a restrição de integridade referencial estabelece que uma tupla de uma relação que se refere à outra relação deve se
referir a uma tupla existente naquela relação.
Por exemplo, na Figura 4.2, o atributo NDEP de EMPREGADO indica o número do departamento que cada empregado
trabalha. Assim, todos os valores de NDEP nas tuplas da relação EMPREGADO devem pertencer ao conjunto de valores
do atributo DNÚMERO da relação DEPARTAMENTO. Para definir formalmente a restrição de integridade referencial,
há a necessidade de, antes, definir o conceito de chave-estrangeira (CE). As condições para uma chave-estrangeira,
descritas abaixo, especificam uma restrição de integridade referencial entre duas relações esquemas R1 e R2.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
45
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Um conjunto de atributos CE na relação esquema R1 será uma chave-estrangeira de R1 se ele satisfizer as seguintes regras:
• os atributos em CE têm o mesmo domínio dos atributos da chave-primária CP da outra relação esquema R
2
.
Diz-se que os atributos CE referenciam ou referem-se à relação R
2
;
• uma CE na tupla t
1
ou tem um valor que ocorre como CP de alguma tupla t
2
de R
2
ou tem o valor null.
No primeiro caso, tem-se t
1
[CE] = t
2
[CP], e diz-se que t
1
referencia ou refere-se à tupla t
2
. Uma base de dados tem
muitas relações e possui muitas restrições de integridade referencial. O projetista deve ter um claro entendimento do
significado ou papel que os atributos desempenham nas diversas relações esquemas da base de dados para que essas
restrições sejam especificadas. Normalmente, as restrições de integridade referencial são derivadas dos relacionamentos
entre entidades representadas pelas relações esquemas. Por exemplo, considere a base de dados mostrada na 4.2.
Na relação EMPREGADO, o atributo NDEP refere-se ao departamento em que cada empregado trabalha; desse modo,
designa-se NDEP como a chave-estrangeira de EMPREGADO, referenciando a relação DEPARTAMENTO. Isso significa que
um valor de NDEP em alguma tupla t1 da relação EMPREGADO deve ter um valor correspondente para a chave-primária
da relação DEPARTAMENTO – o atributo DNÚMERO – em alguma tupla t2 da relação DEPARTAMENTO ou o valor de
NDEP pode ser null se o empregado não pertencer a nenhum departamento. Na Figura 4.2, a tupla do empregado “John
Smith” referencia a tupla departamento de “Pesquisa”, indicando que “John Smith” trabalha para esse departamento.
Note que uma chave-estrangeira pode referenciar sua própria relação.
Por exemplo, o atributo NSSSUPER em EMPREGADO refere-se ao supervisor de um empregado, isto é, outro empregado.
Pode-se, diagramaticamente, mostrar as restrições de integridade desenhando-se arcos direcionados, partindo da chave-
estrangeira para a relação referenciada.
A Figura 4.4 ilustra o esquema apresentado na Figura 4.3, com as restrições de integridade referencial anotadas dessa
maneira.
Caso o projetista tenha interesse em manter as restrições válidas para toda a base de dados, essas restrições de
integridade deveriam ser especificadas no esquema da base de dados relacional.
No sistema relacional, a linguagem de definição de dados (DDL) deveria fornecer recursos para especificar os vários tipos
de restrições tal que o SGDB possa verificá-las automaticamente. Muitos sistemas de gerenciamento de base de dados
relacionais permitem restrições de chave e de integridade de entidade, mas alguns não permitem a integridade referencial.
Figura 4.2. Instâncias da base de dados COMPANHIA
EMPREGADO
PNOME MNOME SNOME NSS DATANASC ENDEREÇO SEXO SALÁRIO NSSSUPER NDEP
John S Smith 123456789 09-JAN-55 R. A. 1 M 3000 3334666 5
Franklin T Wong 333445555 08-DEZ-45 R. B. 2 M 4000 888665565 5
Alicia J Zelaya 999887777 19-JUL58 Av. C. 3 F 2500 987654321 4
Jeniffer S Wallace 987654321 20-JUN-31 Trav. D. 4 F 6300 888664444 4
Ramesh K Narayan 666884444 15-SET-52 R. E. 5 M 3800 333445555 5
Joyce A English 453453453 31-JUL-52 R. F. 6 F 2500 333445565 5
Ahmet V Jabbar 987987987 29-MAR-50 Av. G. 7 M 2500 987654321 4
James E Borg 888665555 10-NOV-27 Av. H. 8 M 5500 null 1
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
46
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
DEPARTAMENTO
DNOME DNÚMERO NSSGER DATINICGER
Pesquisa 5 333445555 22-MAI-78
Administrativo 4 9876543231 01-JAN-85
Gerencial 1 888655555 19-JUN-71
LOCAIS_DEPTO
DNÚMERO DLOCALIZAÇÃO
1 Housson
4 Stafford
5 Bellaire
5 Sugariand
5 Housson
PROJETO
PNOME PNÚMERO PLOCALIZAÇÃO DNUM
ProdutoX 1 Bellaire 5
ProdutoY 2 Sugarland 5
ProdutoZ 3 Houston 5
Automação 10 Stafford 4
Reorganização 20 Houston 1
Beneficiamento 30 Stafford 4
TRABALHA EM
NSSEMP PNRO HORAS
123456789 1 32,5
123456789 2 7,5
666884444 3 40,0
453453453 1 20,0
453453453 2 20,0
333445555 2 10,0
333445555 3 10,0
333445555 10 10,0
999887777 20 10,0
999887777 30 30,0
987987987 10 10,0
987987987 10 35,0
987654321 30 5,0
987654321 30 20,0
321654987 20 Null
DEPENDENTE
NSSEMP NOMEDEPENDENTE SEXO DATANIV RELAÇÃO
333445555 Alice F 05-ABR-76 FILHA
333445555 Theodore M 25-OUT-73 FILHO
333445555 Joy F 03-MAI-48 ESPOSA
987654321 Abner M 29-FEV-78 MARIDO
123456789 Michael M 01-JAN-78 FILHO
123456789 Alice F 31-DEZ-78 FILHA
1234565789 Elizabeth F 05-MAI-57 ESPOSA
Fonte: Adaptado de Takai, Italiano, Ferreira , 2005.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
47
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Figura 4.3. Esquema da base de dados relacional COMPANHIA
EMPREGADO
PNOME MNOME SNOME NSS DATANASC ENDEREÇO SEXO SALÁRIO NSSSUPER NDEP
DEPARTAMENTO
DNOME ONÚMERO NSSGER DATINICGER
LOCAIS_DEPTO
DNÚMERO DLOCALIZAÇÃO
PROJETO
PNOME PNÚMERO PLOCALIZAÇÃO DNUM
TRABALHA EM
NSSEMP PNRO HORAS
DEPENDENTE
NSSEMP NOMEDEPENDENTE SEXO DATANIV RELAÇÃO
Fonte: Adaptado de Takai, italiano, Ferreira, 2005.
Figura 4.4. Esquema COMPANHIA com restrições de integridade
EMPREGADO
PNOME MNOME SNOME NSS DATANASC ENDEREÇO SEXO SALÁRIO NSSSUPER NDEP
DEPARTAMENTO
DNOME ONÚMERO NSSGER DATINICGER
LOCAIS_DEPTO
DNÚMERO DLOCALIZAÇÃO
PROJETO
PNOME PNÚMERO PLOCALIZAÇÃO DNUM
TRABALHA EM
NSSEMP PNRO HORAS
DEPENDENTE
NSSEMP NOMEDEPENDENTE SEXO DATANIV RELAÇÃO
Fonte: Adaptado de Takai, Italiano, Ferreira, 2005.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
48
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Capítulo 5 – Projeto de Banco de Dados Relacional Utilizando o MER
1. Mapeamento do MER para o Modelo de Dados Relacional
Em projetos de banco de dados, é comum que os dados sejam modelados por intermédio de um modelo de dados de
alto-nível. Os produtos gerados por esse processo são os esquemas de visões que são posteriormente integrados para
formar um único esquema.
O Modelo Entidade-Relacionamento (MER) é o modelo de dados de alto-nível normalmente adotado, e o esquema das
visões e de toda a base de dados é especificado em diagramas entidade-relacionamento (DER). O próximo passo a ser
dado para que os dados sejam modelados é o mapeamento do diagrama da base de dados global, obtido na fase anterior,
para um modelo de dados de implementação.
Uma estratégia de tradução, ou de mapeamento, bastante utilizada é a do modelo de dados relacional. Para isso, considere
o esquema relacional mostrado na Figura 5.1, que foi derivado do DER da Figura 3.14, seguindo um procedimento de
mapeamento. Esse procedimento é apresentado passo-a-passo, a partir do exemplo do DER COMPANHIA.
Figura 5.1. Modelo relacional para o esquema COMPANHIA
EMPREGADO
PNOME MNOME SNOME NSS DATANASC ENDEREÇO SEXO SALÁRIO NSSSUPER NDEP
DEPARTAMENTO
DNOME ONÚMERO NSSGER DATINICGER
LOCAIS_DEPTO
DNÚMERO DLOCALIZAÇÃO
PROJETO
PNOME PNÚMERO PLOCALIZAÇÃO DNUM
TRABALHA EM
NSSEMP PNRO HORAS
DEPENDENTE
NSSEMP NOMEDEPENDENTE SEXO DATANIV RELAÇÃO
cp
cp
cp
cp
Ce
cp
cp
Ce
Ce
Ce
Ce
Ce Ce
Ce
Fonte: Adaptado de Takai et al.(2005).
1.1. Passos para o Mapeamento do MER
Passo 1:
Para cada entidade regular E no DER, criar uma relação R que inclua todos os atributos simples de E. Para um atributo
composto, inclua apenas os atributos simples que compõem o atributo composto. Escolha um dos atributos-chave de E
como sendo a chave-primária de R. Se a chave escolhida de E for composta, então o conjunto de atributos simples que o
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
49
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
compõem irão formar a chave-primária de R. No exemplo, foram criadas as relações EMPREGADO, DEPARTAMENTO e
PROJETO, correspondentes às entidades regulares EMPREGADO, DEPARTAMENTO e PROJETO presentes no DER. Os
atributos indicados com CE (chave-estrangeira) ou * (atributos de relacionamento) não foram incluídos ainda; eles serão
adicionados durante os passos subseqüentes. Foram escolhidas as chaves primárias NSS, DNÚMERO e PNÚMERO para
as relações EMPREGADO, DEPARTAMENTO e PROJETO, respectivamente.
Passo 2:
Para cada tipo de entidade fraca W do DER, com o tipo de entidade de identificação E, criar uma relação R e incluir todos
os atributos simples (ou os componentes simples de atributos compostos) de W como atributos de R. Além disso, incluir
como a chave-estrangeira de R a chave-primária da relação que corresponde ao tipo de entidade de identificação; isso
resolve o problema do tipo do relacionamento de identificação de W. A chave-primária de R é a combinação da chave-
primária do tipo de entidade de identificação e a chave-parcial do tipo de entidade fraca W. No exemplo, foi criada a
relação DEPENDENTE, correspondente ao tipo de entidade fraca DEPENDENTE do DER. Foi incluída a chave-primária da
relação EMPREGADO – que corresponde ao tipo de entidade de identificação – como um atributo de DEPENDENTE; foi
renomeado o atributo NSS para NSSEMP, embora não seja necessário. A chave-primária da relação DEPENDENTE é a
combinação {NSSEMP, NOMEDEPENDENTE} porque NOMEDEPENDENTE é chave-parcial de DEPENDENTE.
Passo 3:
Para cada tipo de relacionamento binário 1:1 R do DER, criar as relações S e T, que correspondem aos tipos de entidade
participantes em R. Escolher uma das relações, por exemplo, S, que inclua como chave-estrangeira de S a chave-primária
de T. É melhor escolher o tipo de entidade com participação total em R como a relação S. Inclua todos os atributos simples
(ou os componentes simples de atributos compostos) do tipo de relacionamento 1:1 R como atributos de S. No exemplo,
foi mapeado o tipo de relacionamento 1:1 GERÊNCIA, escolhendo o tipo de entidade participante DEPARTAMENTO para
fazer o papel de S porque sua participação no tipo de relacionamento GERÊNCIA é total (todo departamento tem um
gerente). Foi incluída a chave-primária da relação EMPREGADO como a chave-estrangeira na relação DEPARTAMENTO,
que foi chamado de NSSGER. Também foi incluído o atributo simples Data-Início do tipo de relacionamento GERÊNCIA
na relação DEPARTAMENTO e foi renomeado como DATINICGER. Note-se que uma alternativa para o mapeamento de
um tipo de relacionamento 1:1 seria unir os dois tipos de entidade e o tipo de relacionamento numa única relação. Isso
é particularmente apropriado quando ambas as participações são total e quando os tipos de entidade não participam em
quaisquer outros tipos de relacionamentos.
Passo 4:
Para cada tipo de relacionamento binário regular 1:N (não fraca) R, identificar a relação S, que representa o tipo de
entidade que participa do lado N do tipo de relacionamento. Incluir como chave-estrangeira de S a chave-primária da
relação T, que representa o outro tipo de entidade que participa em R; isso porque cada instância da entidade do lado
1 está relacionada a mais de uma instância de entidade no lado N do tipo de relacionamento. Por exemplo, no tipo de
relacionamento 1:N TRABALHA-PARA cada empregado está relacionado a um único departamento. Incluir também
quaisquer atributos simples (ou componentes simples de atributos compostos) do tipo de relacionamento 1:N como
atributos de S. No exemplo, foram mapeados os tipos de relacionamentos 1:N TRABALHA-PARA e SUPERVISIONA.
Para TRABALHA-PARA incluiu-se a chave-primária da relação DEPARTAMENTO como a chave-estrangeira na relação
EMPREGADO e foi chamado DNUM. Para SUPERVISIONA incluiu-se a chave-primária da relação EMPREGADO como a
chave-estrangeira na relação EMPREGADO e foi denominado NSSSUPER. O relacionamento CONTROLA é mapeado da
mesma maneira.
Passo 5:
Para cada tipo de relacionamento binário M:N R, criar uma nova relação S para representar R. Incluir como chave-estrangeira
em S as chaves-primárias das relações que representam os tipos de entidades participantes; sua combinação irá formar
a chave-primária de S. Incluir também qualquer atributo simples do tipo de relacionamento M:N (ou componentes simples
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
50
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
dos atributos compostos) como atributos de S. Note-se que não se pode representar um tipo de relacionamento M:N como
uma simples chave-estrangeira em uma das relações participantes – como foi feito para os tipos de relacionamentos
1:1 e 1:N – por causa da razão de cardinalidade M:N. Relacionamentos M:N sempre derivam uma nova relação, para o
tipo de relacionamento.
Passo 6:
Para cada atributo A multivalorado, criar uma nova relação R que inclua um atributo correspondendo a A e a chave-primária
K da relação que representa o tipo de entidade ou o tipo de relacionamento que tem A como atributo. A chave-primária
de R é a combinação de A e K. Se o atributo multivalorado é composto, incluir os atributos simples que o compõem.
Passo 7:
Para cada tipo de relacionamento n-ário R, n>2, criar uma nova relação S para representar R. Incluir como chave-
estrangeira em S as chaves-primárias das relações que representam os tipos de entidades participantes. Incluir também
qualquer atributo simples do tipo de relacionamento n-ário (ou componentes simples dos atributos compostos) como
atributo de S. A chave-primária de S é normalmente uma combinação de todas as chaves-estrangeiras e referencia as
relações que representam os tipos de entidades participantes. Porém, se a restrição de participação (min, max) de um
dos tipos de entidades E que participa em R tiver max=1, então a chave-primária de S pode ser a chave-estrangeira que
referencia a relação E’ correspondente a E; isso porque cada entidade em E irá participar em apenas uma instância de R
e, portanto, pode identificar univocamente essa instância de relacionamento.
O principal ponto que deve ser considerado em um esquema relacional, quando comparado ao esquema do MER, é que
os tipos de relacionamento não são representados explicitamente; eles são representados por dois atributos A e B, um
para a chave-primária e outra para a chave-estrangeira – sobre o mesmo domínio – incluídos em duas relações S e T.
Duas tuplas em S e T estão relacionadas quando elas tiverem o mesmo valor para A e B, ou seja, os relacionamentos
são definidos pelos valores dos atributos A e B.
Figura 5.2. Exemplo de mapeamento de um relacionamento ternário
FORNECEDOR
FNOME ...
PROJETO
PNOME ...
PEÇA
NÚMERO ...
FORNECE
FNOME PNOME NÚMERO QUANTIDADE
Fonte: Adaptado de Takai et al.(2005).
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
51
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
A Figura 5.3 mostra uma representação esquemática dos passos que devem ser seguidos para a tradução de um MER.
Figura 5.3. Representação esquemática dos passos para o mapeamento do MER.
Fonte: Adaptado de Takai, italiano, Ferreira, 2005.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
52
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Capítulo 6 – SQL – Structured Query Language
1. Introdução
No início dos anos 1970, no laboratório de San José, surgiu a Linguagem SQL, como fruto de um projeto da IBM.
Empenhavam-se num projeto de uma linguagem que se adequasse ao modelo relacional. Esse projeto trabalhava em
paralelo com outro que visava desenvolver um sistema de gerência de Banco de Dados relacional, chamado “System R”.
O primeiro sistema de Banco de Dados baseado em SQL tornou-se disponível comercialmente no final dos anos 1970.
A primeira versão padronizada da linguagem SQL foi publicada em meados de 1980 e dois institutos trabalharam na
sua padronização, o ANSI e o ISO. Desde então, a linguagem vem evoluindo e culminando na criação de novas versões
padronizadas, tais como a versão SQL-92 e a SQL-99, assim chamadas em referência aos anos em que foram publicadas.
Figura 6.1. Ambiente da linguagem SQL
A linguagem SQL é utilizada na grande maioria dos sistemas de Bancos de Dados relacionais, tais como MySQL, DB2,
SQLServer, e se tornou a mais poderosa ferramenta de definição e manipulação de Bancos de Dados relacionais.
2. Aplicabilidade e Uso
A linguagem SQL é bem diferente das linguagens comuns de programação por ser, basicamente, uma linguagem de
consulta a banco de dados. Ao contrário da maioria das linguagens de programação, a linguagem SQL não é uma linguagem
procedural
1
. Na linguagem SQL não se especifica como ou em que ordem serão executados os processos que irão fornecer
os resultados requeridos; eles são apenas informados com base nos resultados desejados. Desse modo, o sistema de
banco de dados é o responsável por escolher adequadamente os procedimentos a serem executados, de forma que os
resultados sejam obtidos com a maior eficiência possível.
Com a Linguagem SQL podemos tanto definir e construir relações, como manipular diversas relações, de forma a obter
resultados desejados. Por isso, ela é considerada uma linguagem de definição e de manipulação de dados.
1 Linguagem de programação na qual o elemento básico de programação é a procedure (uma sequência de instruções – rotina, sub-rotina ou função – associadas a um nome próprio).
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
53
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
A linguagem SQL pode estar presente numa imensa quantidade de sistemas de banco de dados, estando visível ou mascarada
(embutida). Na forma visível o usuário digita os comandos na linguagem SQL diretamente em um prompt de comando, de
onde também é possível visualizar os resultados. Já na forma embutida, a linguagem SQL não está visível diretamente
ao usuário; os programadores podem embutir os comandos em SQL, dentro de um programa, e criar uma interface mais
amigável com o usuário comum – esse pode interagir mais facilmente com a interface do que com a própria linguagem SQL.
Dessa forma, usuários comuns podem manipular um banco de dados sem mesmo ter algum conhecimento sobre de SQL.
A linguagem SQL é composta por um conjunto de declarações que é usado para acessar os dados utilizando gerenciadores
de banco de dados. Nem todos os gerenciadores utilizam SQL.
Uma entrada SQL é constituída por uma sequência de comandos onde um comando é composto por uma sequência de
termos (tokens
1
), terminada por um ponto-e-vírgula (“;”). O fim do fluxo de entrada também termina o comando, sendo
válido os termos dependendo da sintaxe particular de cada comando.
Um termo pode ser uma palavra-chave, um identificador, um identificador entre aspas, um literal (ou constante), ou um
caractere especial. Geralmente, os termos são separados por espaço em branco (espaço, tabulação ou nova-linha), mas
não há necessidade se não houver ambiguidade (normalmente só acontece quando um caractere especial está adjacente
a um termo de outro tipo). Além disso, podem existir comentários na entrada SQL e esses comentários não são termos,
constituindo-se, na realidade, em equivalentes a espaço em branco.
A seguir é apresentada uma entrada SQL, sintaticamente válida para servir de exemplo.
Figura 6.2. Exemplo de uma entrada SQL sintaticamente válida
SELECT * FROM MINHA_TABELA;
UPDATE MINHA_TABELA SET A = 5;
INSERT INTO MINHA_TABELA VALUES (3, ‘oi você’);
A sequência apresentada na Figura 6.2 consiste de uma sequência de três comandos, um por linha. Mesmos não existindo
um limitador que obrigue que a sintaxe seja escrita dessa forma, pode haver mais de um comando na mesma linha, e um
único comando pode ocupar várias linhas.
A sintaxe da linguagem SQL não diferencia claramente quais termos identificam comandos e quais são operandos ou
parâmetros. Em geral, os primeiros termos são o nome do comando e, portanto, no exemplo da Figura 6.2 pode-se dizer
que estão presentes os comandos “SELECT”, “UPDATE” e “INSERT”. Entretanto, para exemplificar, o comando UPDATE
sempre requer que o termo SET apareça em uma determinada posição, e essa forma particular do comando INSERT
também requer a presença do termo VALUES para estar completa. As regras precisas da sintaxe de cada comando
estão descritas na Parte VI.
2.1. Identificadores e Palavras-Chave
Os termos SELECT, UPDATE e VALUES mostrados no exemplo da Figura 6.2 são exemplos de palavras-chave, ou
seja, palavras que possuem um significado definido na linguagem SQL. Os termos MINHA_TABELA e A são exemplos
de identificadores, os quais identificam nomes de tabelas, colunas e outros objetos do banco de dados, dependendo do
comando onde são utilizados. Portanto, algumas vezes são simplesmente chamados de “nomes”. As palavras-chave e os
identificadores possuem a mesma estrutura léxica, significando que não é possível saber se o termo é um identificador
ou uma palavra chave sem conhecer a linguagem.
Os identificadores e as palavras-chave do SQL devem iniciar por uma letra (a-z e, também, letras com diacrítico
2
– áéç...
– e letras não latinas), ou o caractere sublinhado (_). Os demais caracteres de um identificador, ou da palavra-chave,
1 Token em computação é um segmento de texto ou símbolo que pode ser manipulado por um parser, que fornece um significado ao texto; em outras palavras, é um conjunto de
caracteres (de um alfabeto, por exemplo) com um significado coletivo.
2 diacrítico — do Gr. diakritikós, que se pode distinguir — diz-se dos sinais gráficos com que se notam os caracteres alfabéticos para lhe dar um valor especial
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
54
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
podem ser letras, sublinhados, dígitos (0-9) ou o cifrão ($). Deve ser observado que, de acordo com o padrão SQL, o
cifrão não é permitido em identificadores e, portanto, pode tornar a aplicação menos portável. O padrão SQL não irá
definir palavra-chave contendo dígitos, ou começando ou terminando por sublinhado e, portanto, os identificadores com
essa forma estão a salvo contra possíveis conflitos com extensões futuras do padrão.
O sistema não utiliza mais que NAMEDATALEN-1 caracteres de um identificador; podem ser escritos nomes mais
longos nos comandos, mas são truncados. Por padrão, NAMEDATALEN é 64 e, portanto, o comprimento máximo de
um identificador é 63. Se esse limite causar problema, pode ser aumentado, modificando a constante NAMEDATALEN.
Os identificadores e as palavras-chave não fazem distinção entre letras maiúsculas e minúsculas. Portanto, a expressão
“UPDATE MINHA_TABELA SET A = 5;” também pode ser escrita como “uPdAtE Minha_TaBeLa SeT a = 5;”.
De forma geral, utiliza-se a convenção de escrever as palavras-chave em letras maiúsculas e os nomes em letras minúsculas,
tornando a expressão da seguinte forma: “UPDATE minha_tabela SET a = 5;”.
Um segundo tipo de identificador é o identificador delimitado ou identificador entre aspas, formado pela colocação de
uma sequência arbitrária de caracteres entre aspas (“). Um identificador delimitado é sempre um identificador, e
nunca uma palavra-chave. Portanto, a expressão “select” pode ser usada para fazer referência a uma tabela ou coluna
chamada “select”, enquanto select sem aspas sempre é uma palavra-chave ocasionando, por isso, um erro do analisador
quando usado onde um nome de tabela ou de coluna for esperado.
Identificadores entre aspas podem conter qualquer caractere que não sejam as próprias aspas. Essa funcionalidade
permite criar nomes de tabelas e de colunas que não seriam possíveis de outra forma, como os contendo espaços ou
e-comercial (&). O limite do comprimento ainda se aplica.
A linguagem SQL diferencia as letras maiúsculas de minúsculas ao colocarmos um identificador entre aspas, enquanto
as letras dos nomes não delimitados por aspas são sempre convertidas em minúsculas. Por exemplo, os identificadores
“FOO” e foo são considerados o mesmo identificador.
2.2. Constantes
A linguagem SQL
1
define, basicamente, três tipos de constante com tipo implícito. São eles: cadeias de caracteres,
cadeias de bits e numéricas. As constantes também podem ser especificadas com tipo explícito, o que permite uma
representação mais precisa, e um tratamento mais eficiente por parte do sistema.
2.2.1. Constantes do Tipo Cadeia de Caracteres
Uma constante cadeia de caracteres no SQL é uma sequência arbitrária de caracteres envolta por apóstrofos (‘).
Exemplificando, suponhamos a seguinte expressão: ‘Esta é uma cadeia de caracteres’.
A forma de escrever um apóstrofo dentro de uma constante cadeia de caracteres, em conformidade com o padrão
SQL, é colocar dois apóstrofos adjacentes como, por exemplo, ‘Maria D’’Almeida’. Alguns SGBDs permitem, também, a
utilização da contrabarra (“\”) como caractere de escape para colocar apóstrofos dentro de cadeia de caracteres como,
por exemplo, ‘Maria D\’Almeida’.
O SGBD PostgreSQL permite a utilização dos escapes de contrabarra no estilo da linguagem C. Comando como o “\b”
para voltar apagando (backspace), “\f” para avanço de formulário (form feed), “\n” para nova-linha, “\r” para retorno do
carro, “\t” para tabulação e “\xxx”, onde “xxx” é um número octal, é o byte com o código. Nesse caso, para incluir uma
contrabarra em uma constante do tipo cadeia de caracteres devem ser escritas duas contrabarras adjacentes.
1 A quantidade de tipos de constantes pode variar conforme o Sistema Gerenciado de Banco de Dados que usa a linguagem SQL.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
55
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Na linguagem SQL, duas constantes cadeias de caracteres separadas apenas por espaço em branco com pelo menos um
caractere de nova-linha, são concatenadas e tratadas efetivamente como se a cadeia de caracteres tivesse sido escrita
em uma constante. Desse modo, vejamos a expressão descrita na Figura 6.3. Porém, a expressão “SELECT ‘foo’ ‘bar’;”
é interpretada como uma expressão de sintaxe inválida.
2.2.2. Constantes do Tipo Cadeia de Bits
Uma constante do tipo cadeia de bits se parece com uma constante do tipo cadeia de caracteres contendo a letra B
(maiúscula ou minúscula) imediatamente antes do apóstrofo de abertura (sem espaços separadores) como, por exemplo,
B’1001’. Os únicos caracteres permitidos dentro de uma constante do tipo cadeia de bits são 0 e 1.
Figura 6.3. Exemplo de uma constante de caracteres.
SELECT ‘foo’
‘bar’;
Equivale a:
SELECT ‘foobar’;
Como forma alternativa, constantes do tipo cadeia de bits podem ser especificadas usando a notação hexadecimal,
colocando a letra X (maiúscula ou minúscula) no início como, por exemplo, X’1FF’. Essa notação equivale a uma constante
do tipo cadeia de bits contendo quatro dígitos binários para cada dígito hexadecimal.
As duas formas de constantes do tipo cadeia de bits podem ocupar mais de uma linha, da mesma forma que uma constante
do tipo cadeia de caracteres.
2.2.3. Constantes Numéricas
De forma geral, são aceitas constantes numéricas nas seguintes formas gerais:
dígitos
dígitos.[dígitos][e[+-]dígitos]
[dígitos].dígitos[e[+-]dígitos]
dígitos[e[+-]dígitos
Nas formas gerais descrita, dígitos são um ou mais dígitos decimais (0 a 9), devendo haver pelo menos um dígito antes
ou depois do ponto decimal, caso esse seja usado.
Deve haver, também, pelo menos um dígito após a marca de expoente (e), caso esteja presente. Não podem existir
espaços ou outros caracteres incorporados à constante. Deve ser observado que os sinais menos e mais que antecedem
a constante não são, na verdade, considerados parte da constante, e sim um operador aplicado à constante.
Abaixo são mostrados alguns exemplos de constantes numéricas válidas:
42
3.5
4.
.001
5e2
1.925e-3
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
56
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Uma constante numérica não contendo o ponto decimal nem o expoente é presumida, inicialmente, como sendo do tipo
integer se o seu valor for apropriado para o tipo integer (32 bits); senão, é presumida como sendo do tipo bigint, se o seu
valor for apropriado para o tipo bigint (64 bits); caso contrário, é assumida como sendo do tipo numeric. As constantes
que contêm pontos decimais e/ou expoentes são sempre presumidas, inicialmente como sendo do tipo numeric.
O tipo de dado atribuído inicialmente para a constante numérica é apenas o ponto de partida para os algoritmos de resolução
de tipo. Na maioria dos casos, a constante é automaticamente convertida no tipo mais apropriado conforme o contexto.
2.2.4. Constantes de Outros Tipos
Pode ser declarada uma constante de um tipo arbitrário utilizando uma das seguintes notações:
tipo ‘cadeia de caracteres’
‘cadeia de caracteres’::tipo
O texto da constante cadeia de caracteres é passado para a rotina de conversão da entrada para o tipo chamado tipo. O
resultado é uma constante do tipo indicado. A conversão explícita de tipo pode ser omitida caso não haja ambiguidade
com relação ao tipo que a constante deva ter (por exemplo, quando é atribuída diretamente para uma coluna de uma
tabela), e nesse caso é convertida automaticamente.
Também é possível especificar a conversão de tipo utilizando a sintaxe semelhante à chamada de função: “nome_do_tipo
( ‘cadeia de caracteres’ )”. Porém, nem todos os nomes de tipo podem ser usados dessa forma.
2.3. Operadores
A linguagem SQL define que um nome de operador é uma sequência com até NAMEDATALEN-1 (por padrão 63) caracteres
da seguinte lista:
+ - * / < > = ~ ! @ # % ^ & | ` ?
Porém, existem algumas restrições para os nomes de operadores:
• Não podem ocorrer as sequências -- e /* em nenhuma posição no nome do operador, porque são consideradas
início de comentário.
• Um nome de operador com vários caracteres não pode terminar por + ou por -, a não ser que o nome também
contenha ao menos um dos seguintes caracteres: ~ ! @ # % ^ & | ` ?. Por exemplo, @- é um nome de
operador permitido, mas *- não é.
2.4. Caracteres Especiais
Alguns caracteres não alfanuméricos possuem significado especial diferente de ser um operador.
• O caractere cifrão ($) seguido por dígitos é utilizado para representar parâmetros posicionais no corpo da
definição de uma função. Em outros contextos, o caractere cifrão pode ser parte de um identificador.
• Os parênteses (()) possuem seu significado usual de agrupar expressões e impor a precedência. Em alguns
casos, os parênteses são requeridos como parte da sintaxe fixada para um determinado comando SQL.
• Os colchetes ([]) são utilizados para selecionar elementos da matriz.
• As vírgulas (,) são utilizadas em algumas construções sintáticas para separar elementos da lista.
• O ponto-e-vírgula (;) termina um comando SQL, não podendo aparecer em nenhum lugar dentro do comando,
exceto dentro de constantes do tipo cadeia de caracteres ou identificadores entre aspas.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
57
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
• Os dois-pontos (:) são utilizados para selecionar “fatias” de matrizes. Em certos dialetos do SQL, como a
linguagem SQL incorporada, os dois-pontos são utilizados como prefixo dos nomes das variáveis.
• O asterisco (*) é utilizado em alguns contextos para denotar todos os campos da linha de uma tabela ou de
um valor composto. Também possui um significado especial quando utilizado como argumento da função de
agregação COUNT.
• O ponto (.) é utilizado nas constantes numéricas, e para separar os nomes de esquemas, tabelas e colunas.
2.5. Comentários
A linguagem SQL define que um comentário é uma sequência arbitrária de caracteres começando por dois hífens e
prosseguindo até o fim da linha como, por exemplo, a expressão “Este é um comentário em conformidade com o padrão
SQL-99”. Alternativamente, é possível utilizarem-se blocos de comentários no estilo da linguagem C, conforme apresentado
na Figura 6.4, onde o comentário começa por /* e se estende até encontrar a ocorrência correspondente de */. Esses
blocos de comentários podem estar aninhados, conforme especificado no padrão SQL, mas diferentemente da linguagem
C, permitindo transformar em comentário grandes blocos de código contendo blocos de comentários.
Os comentários são removidos do fluxo de entrada antes de prosseguir com a análise sintática, sendo substituídos por
espaço em branco.
Figura 6.4. Exemplo de comentários utilizando o formato da linguagem C
/* comentário de várias linhas
* com aninhamento: /* bloco de comentário aninhado */
*/
2.6. Precedência Léxica
Um item léxico, também chamado de token, é uma unidade básica do texto correspondente ao programa fonte sendo,
normalmente, representado internamente pelo analisador léxico por três funções:
• Classe: diz respeito à classificação léxica do token. Sob essa ótica, um item pode ser classificado, por
exemplo, com sendo um identificador, uma constante, um operador ou mesmo uma sequência de caracteres.
• Valor ou Lexema: diz respeito ao valor léxico do token, que depende da classe e pode ser categorizado como:
– Token Simples: são aqueles que não possuem argumentos uma vez que sua classe os define completamente.
Ex. operadores matemáticos, relacionais, lógicos.
– Token com Argumento: são aqueles que possuem um valor associado e correspondem aos elementos da
linguagem definidos pelo programador. Ex. o valor de uma constante numérica.
• Posição: diz respeito ao que identifica a localização do token no programa fonte, auxiliando no processo de
correção de erros.
A precedência léxica diz respeito à ordem de processamento dos comandos por parte do analisador léxico, sendo que a
maioria dos operadores possui a mesma precedência e associatividade esquerda. A precedência e a associatividade dos
operadores estão codificadas no analisador léxico, podendo ocasionar um comportamento contra-intuitivo. Exemplificando,
os operadores booleanos “<” e “>” possuem uma precedência diferente dos operadores booleanos “<=” e “>=”.
Também, em alguns casos é necessário adicionar parênteses ao utilizar uma combinação de operadores unários e
binários. Tomemos a expressão “SELECT 5! – 6;” para análise. Caso a expressão seja apresentada conforme descrita, o
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
58
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
interpretador a analisará como “SELECT 5! (-6);”, o que decorre do fato de que o interpretador não tem como identificar
que o símbolo “!” é definido como operador unário-direito e não um operador binário que foi colocado entre os operandos.
Para que a expressão seja interpretada corretamente, é necessário apresentá-la com o uso adequado do parêntese e deve
ser escrita como “SELECT (5!) – 6;”. A título de exemplo, a tabela 6.1 apresenta a precedência e a associatividade
dos operadores no PostgreSQL.
2. Definição de Dados Utilizando SQL
Nos bancos de dados relacionais, os dados são armazenados em tabelas, portanto, é necessário entender como as tabelas
são criadas e modificadas, e as funcionalidades disponíveis para controlar que dados podem ser armazenados nas tabelas.
2.1. Noções Básicas de Tabela
Uma tabela em um banco de dados relacional é muito semelhante a uma tabela no papel: é formada por linhas e colunas.
O número e a ordem das colunas são fixos, e cada coluna possui um nome. O número de linhas é variável, refletindo a
quantidade de dados armazenados em um determinado instante. O padrão SQL não dá nenhuma garantia sobre a ordem
das linhas na tabela.
Quando a tabela é lida, as linhas aparecem em uma ordem aleatória, a não ser que a classificação seja requisitada
explicitamente. Além disso, o SQL não atribui identificadores únicos para as linhas e, portanto, é possível existirem
várias linhas totalmente idênticas na tabela. Isto é uma consequência do modelo matemático subjacente ao SQL, mas
geralmente não é desejável. Mais adiante, neste capítulo, será mostrado como lidar com essa questão.
Tabela 6.1. Precedência dos operadores em ordem Decrescente
Operador/Elemento Associatividade Descrição
. esquerda separador de nome de tabela/coluna
:: esquerda conversão de tipo estilo PostgreSQL
[ ] esquerda seleção de elemento de matriz
- direita menos unário
^ esquerda exponenciação
* / % esquerda multiplicação, divisão, módulo
+ - esquerda adição, subtração
IS IS TRUE, IS FALSE, IS UNKNOWN, IS NULL
ISNULL teste de nulo
NOTNULL teste de não nulo
(qualquer outro) esquerda os demais operadores nativos e os definidos pelo usuário
IN membro de um conjunto
BETWEEN contido em um intervalo
OVERLAPS sobreposição de intervalo de tempo
LIKE ILIKE SIMILAR correspondência de padrão em cadeia de caracteres
< > menor que, maior que
= direita igualdade, atribuição
NOT direita negação lógica
AND esquerda conjunção lógica
OR esquerda disjunção lógica
Cada coluna de uma tabela possui um tipo de dado que é o fator que restringe o conjunto de valores que podem ser
atribuídos à coluna e atribui semântica
1
aos dados armazenados na coluna. Cada SGBD possui um conjunto de tipos
1 semântica — do Gr. semantiké, da significação — estudo da linguagem humana do ponto de vista do significado das palavras e dos enunciados. PRIBERAM - Língua Portuguesa
On-Line . (N. do T.)
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
59
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
de dado nativos, adequados para muitas aplicações e, de forma geral, os usuários também podem definir seus próprios
tipos de dado.
Alguns dos tipos de dado mais utilizados são o integer para números inteiros, numeric para números possivelmente
fracionários, text para cadeias de caracteres, date para datas, time para valores da hora do dia, e timestamp para valores
contendo tanto data quanto hora.
2.2. Criação de Tabelas
Para criar uma tabela utiliza-se o comando CREATE TABLE. Esse comando necessita que sejam especificados, ao menos,
o nome da nova tabela, os nomes das colunas, e o tipo de dado de cada coluna (Figura 6.4).
A sintaxe do comando é:
CREATE TABLE tabela (campo1 tipo [(tamanho)] [NOT NULL] [índice1] [, campo2 tipo [(tamanho)] [NOT NULL] [índice2]
[, ...]] [, CONSTRAINT índicedemulticampos [, ...]])
Os elementos da sintaxe do comando CREATE TABLE são apresentados na Tabela 6.2.
Tabela 6.2. Elementos do Comando CREATE TABLE
Parte Descrição
tabela O nome da tabela a ser criada.
campo1, campo2 O nome do campo ou campos a serem criados na nova tabela. Uma tabela deve
ter pelos menos um campo.
tipo O tipo de dados de campo na nova tabela.
tamanho O tamanho do campo em caracteres (somente os campos Texto e Binário)
índice1, índice2 Uma cláusula CONSTRAINT que define um índice de campo único.
indice de multicampos Uma cláusula CONSTRAINT que define um índice hde campos múltiplos.
A sintaxe da Figura 6.5 cria a tabela chamada “minha_primeira_tabela” contendo duas colunas, onde a primeira coluna
é denominada “primeira_coluna” e possui o tipo de dado text, e a segunda coluna chama-se “segunda_coluna” e possui
o tipo de dado integer. É necessário observar que a lista de colunas deve ser envolta por parênteses e os elementos da
lista separados por vírgula.
Figura 6.5. Exemplo de Expressão para a Criação de uma Tabela
CREATE TABLE minha_primeira_tabela (
primeira_coluna text,
segunda_coluna integer
);
De forma geral, são dados nomes para as tabelas e para as colunas condizentes com as informações armazenadas
(Figura 6.6.)
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
60
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Figura 6.6. Exemplo de Expressão para a Criação de uma Tabela
CREATE TABLE produtos (
cod_prod integer not null,
nome text (30),
preco decimal (7,2)
);
Existe um limite quanto à quantidade de colunas que uma tabela pode conter – pode variar entre 250 e 1600, dependendo
dos tipos de dados das colunas.
Dica 1: Quando são criadas tabelas inter-relacionadas, é aconselhável escolher um padrão coerente para
atribuir nomes às tabelas e colunas.
Dica 2: A restrição not null indica que o atributo deve ser obrigatoriamente preenchido; se não for especificado,
então o “default” é que o atributo possa assumir o valor nulo.
2.3. Remoção de Tabelas
Caso uma tabela não seja mais necessária, é possível removê-la utilizando-se o comando DROP TABLE sintaxe do
comando é:
DROP {TABLE tabela | INDEX índice ON tabela}
Os elementos da sintaxe do comando DROP TABLE são apresentados na Tabela 6.3.
Tabela 6.3. Elementos do Comando DROP TABLE.
Parte Descrição
Tabela O nome da tabela a ser excluída ou a tabela a partir da qual um índice deve ser
excluido.
Índice O nome do índice a ser excluído da tabela.
Figura 6.7. Exemplo de Remoção de uma Tabela.
DROP TABLE minha_primeira_tabela;
DROP TABLE produtos;
Dica 1: Observe que, no caso em que a chave primária da tabela removida é composta de elementos de
diversas outras tabelas, essas devem ser devidamente corrigidas. Isso pode resultar na alteração do projeto
físico de diversas tabelas e acabar implicando a construção de uma nova base de dados.
2.4. Inclusão de Atributos em uma Tabela
O comando ALTER TABLE permite que o usuário faça a inclusão de novos atributos em uma tabela (Figura 6.8.). A
sintaxe do comando é:
ALTER TABLE tabela {ADD {COLUMN campo tipo[(tamanho)] [NOT NULL] [CONSTRAINT índice] | CONSTRAINT
índicedemulticampos} | DROP {COLUMN campo I CONSTRAINT nomedoíndice} }
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
61
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Os elementos da sintaxe do comando ALTER TABLE são apresentados na Tabela 6.4.
Figura 6.8. Exemplo de Inclusão de Coluna em uma Tabela
ALTER TABLE minha_primeira_tabela add terceira_coluna interger;
Tabela 6.4. Elementos do Comando ALTER TABLE
Parte Descrição
Tabela O nome da tabela a ser alterada.
Campo O nome do campo a ser adicionado ou excluído da tabela.
Tipo O tipo de dados de campo.
Tamanho O tamanho do campo em caracteres (somente os campos Texto e Binário).
Índice O índice para campo.
Índicedemulticampos A definição de um índice de campos múltiplos a ser adicionado à tabela.
NomedoÍndice O nome do índice de campo múltiplo a ser removido.
Além de permitir adicionar colunas em uma tabela, no comando ALTER TABLE, você pode alterar uma tabela existente
utilizando:
• ADD CONSTRAINT para adicionar um índice de campos múltiplos. (Para maiores informações sobre índices
de campos múltiplos, consulte o tópico da cláusula CONSTRAINT).
• DROP COLUMN para excluir um campo. Você especifica somente o nome do campo.
• DROP CONSTRAINT para excluir um índice de campos múltiplos. Você especifica somente o nome do índice
após a palavra reservada CONSTRAINT.
• NOT NULL em um campo único ou dentro de uma cláusula CONSTRAINT nomeada, que se aplica a uma
CONSTRAINT de campo único ou campos múltiplos. Contudo, você pode aplicar a restrição NOT NULL
somente uma vez a um campo pois, senão, ocorrerá um erro em tempo de execução.
Você não pode adicionar ou excluir mais de um campo ou índice de cada vez.
Dica 1: No caso do comando ALTER TABLE, a restrição NOT NULL não é permitida, pois assim que se insere
um novo atributo na tabela, o valor para o mesmo em todas as tuplas da tabela receberão o valor NULL.
2.5. Colunas do Sistema
Implicitamente definidas pelo SGBD, toda tabela possui diversas colunas do sistema. Desse modo, esses nomes não
podem ser utilizados como nomes de colunas definidas pelo usuário. A Tabela 6.5 apresenta os nomes usuais das colunas
do sistema.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
62
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Tabela 6.5. Nome das Colunas do Sistema
Nome Descrição
oid
É o identificador de objeto (object ID) de uma linha e consiste de um número serial adicionado
pelo SGBD, automaticamente, a todas as linhas da tabela (a não ser que a tabela seja criada
com WITHOUT OIDS e, nesse caso, esta coluna não estará presente). O tipo desta coluna é
oid (o mesmo nome da coluna).
tableoid
É o OID da tabela que contém esta linha. Esse atributo é particularmente útil nas consultas
fazendo seleção em hierarquias de herança, porque sem ele é difícil saber de que tabela se
origina cada linha. Pode ser feita uma junção entre tableoid e a coluna oid de pq_class para
obter o nome da tabela.
xmin
É o identificador da transação de inserção (transaction ID) para esta versão da linha. Uma
versão da linha é um estado individual da linha; cada atualização da linha cria uma nova versão
de linha para a mesma linha lógica.
cmin É o identificador do comando, começando por zero, dentro da transação de inserção.
xmax
É o identificador da transação de exclusão (transaction ID), ou zero para uma versão de linha
não excluída.
cmax É o identificador do comando dentro da transação de exclusão, ou zero.
ctid É a localização física da versão da linha dentro da tabela.
Os OIDs, os identificadores de transações e os identificadores de comandos são quantidades de 32 bits atribuídas a partir
de um contador único para todo o agrupamento de bancos de dados. Na prática, essas quantidades criam um limite de
232 (4 bilhões) de comandos SQL dentro de uma única transação.
Dica 1: Deve-se observar que essa restrição de uso do nome de uma coluna definida pelo sistema é diferente
do nome ser uma palavra-chave ou não, pois colocar o nome entre aspas não faz esta restrição deixar de
ser aplicada.
3. Especificando as Restrições Básicas em SQL
Apesar dos tipos de dados funcionarem como uma forma de limitar os dados que podem ser armazenados em uma tabela,
várias aplicações necessitam de restrições com um refinamento maior. Em uma tabela, onde uma coluna que contenha
dados sobre preços de produtos deveria, em princípio, aceitar apenas valores positivos. Porém, não existe qualquer tipo
de dado que aceite, apenas esses valores. Outro problema bastante comum é a situação em que essa mesma tabela de
produtos necessita limitar a inserção de produtos de forma que exista apenas uma linha para cada código de produto.
A linguagem SQL permite que sejam definidas restrições quanto a colunas e tabelas, de forma a controlar os dados
que são armazenados nela. Desse modo, é possível impedir que o usuário armazene dados em uma coluna da tabela
que acabe por violar a integridade do conteúdo. Tais restrições permitem que se tenha controle sobre os dados que são
armazenados na tabela.
3.1. Restrições de Verificação
3.1.1. Restrições de Coluna
Entre os tipos de restrições existentes, a restrição de verificação é a mais genérica, pois permite que sejam especificados
os valores que podem ser armazenados em uma determinada coluna para estar de acordo com uma expressão booleana
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
63
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
(valor-verdade
1
). Na Figura 6.9, é apresentada uma expressão onde é verificado se os valores relativos aos preços são
positivos.
Figura 6.9. Exemplo de Restrição de Verificação em uma Coluna de uma Tabela
CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric CHECK (preco > 0)
);
Na linguagem SQL, a definição da restrição vem após o tipo de dado, assim como a definição do valor padrão. Já o
valor padrão e a restrição podem estar em qualquer ordem, sendo que a restrição de verificação é formada pela palavra
chave CHECK, seguida por uma expressão entre parênteses. Cabe salientar que a expressão da restrição de verificação
necessita envolver a coluna sendo restringida.
Por outro lado, também é possível atribuir um nome individual para a restrição, tornando a mensagem de erro mais clara
e permitindo fazer referência à restrição quando se desejar alterá-la (Figura 6.10).
Figura 6.10. Exemplo de Restrição de Verificação em uma Coluna Atribuindo um Nome para a Restrição
CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric CONSTRAINT chk_preco_positivo CHECK (preco > 0)
);
A palavra-chave CONSTRAINT permite que seja atribuído um nome para a restrição e deve ser seguida por um identificador
(nome que será dado à restrição) e um valor que definirá a restrição.
Além disso, é possível definir uma restrição de verificação que referencie mais de uma coluna. Na Figura 6.11, temos
uma expressão onde é verificado o valor armazenado tanto do preço quanto do preço com desconto. Nesse caso, o que
se espera é que o valor relativo ao preço seja maior do que o valor relativo ao preço com desconto.
Figura 6.11. Exemplo de Restrição de Verificação em uma Coluna Referenciando mais de uma Coluna
CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric CHECK (preco > 0),
preco_com_desconto numeric CHECK (preco_com_desconto > 0),
CHECK (preco > preco_com_desconto)
);
1 Na lógica, o valor-verdade (truth-value) é um valor indicando até que ponto uma declaração é verdadeira.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
64
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
3.1.2. Restrições de Tabela
Diferentemente da restrição de coluna, a restrição de tabela utiliza uma nova sintaxe, e não está anexada a uma coluna
em particular, aparecendo como um item à parte na lista de colunas separadas por vírgula. As definições das colunas e
as definições dessas restrições podem estar em qualquer ordem.
As Figuras 6.12 e 6.13 apresentam o exemplo da Figura 6.9, reescrito na forma de restrição de tabela.
Figura 6.12. Exemplo de Restrição de Verificação em uma Tabela (Sintaxe I)
CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric,
CHECK (preco > 0),
preco_com_desconto numeric,
CHECK (preco_com_desconto > 0),
CHECK (preco > preco_com_desconto)
);
Figura 6.13. Exemplo de Restrição de Verificação em uma Tabela (Sintaxe II)
CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric CHECK (preco > 0),
preco_com_desconto numeric,
CHECK (preco_com_desconto > 0 AND preco > preco_com_desconto)
);
3.2. Restrições de Não Nulo
Uma Restrição de Não Nulo define que o valor de uma coluna não pode ser nulo, ou seja, que necessita conter algum valor
(Figura 6.14). Cabe lembrar que uma Restrição de Não Nulo é sempre escrita como restrição de coluna e não uma restrição
de tabela, sendo que essa é funcionalmente equivalente a criar uma restrição de verificação CHECK (nome_da_coluna
IS NOT NULL.
Como uma coluna pode possuir mais de uma restrição, para considerar todas as restrições necessárias, basta escrever
uma restrição em seguida da outra (Figura 6.15), sendo que a ordem em que as restrições são escritas não determina
necessariamente sua ordem de checagem.
Figura 6.14. Exemplo de Restrição de Não Nulo
CREATE TABLE produtos (
cod_prod integer NOT NULL,
nome text NOT NULL,
preco numeric
);
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
65
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Figura 6.15. Exemplo de Mais de uma Restrição
CREATE TABLE produtos (
cod_prod integer NOT NULL,
nome text NOT NULL,
preco numeric NOT NULL CHECK (preco > 0)
);
Dica 1: Em grande parte dos projetos de banco de dados, a maioria das colunas deve ser especificada como
não-nula.
3.3. Restrições de Unicidade
A restrição de unicidade procura garantir que os dados contidos em uma coluna, ou mesmo em um grupo de colunas,
seja único com relação a todas as outras linhas da tabela. A Figura 6.16 apresenta um exemplo desse tipo de restrição
aplicada a uma coluna e a Figura 6.17, um exemplo desta mesma restrição aplicada a uma tabela.
Figura 6.16. Exemplo de Restrição de Unicidade aplicada a uma Coluna
CREATE TABLE produtos (
cod_prod integer UNIQUE,
nome text,
preco numeric
);
Figura 6.17. Exemplo de Restrição de Unicidade aplicada a uma Tabela
CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric,
UNIQUE (cod_prod)
);
Caso uma restrição de unicidade faça referência a um grupo de colunas, essas devem ser listadas separadas por vírgula,
conforme a Figura 6.18. Esse tipo de restrição especifica que a combinação dos valores das colunas indicadas deve ser
única para toda a tabela, embora não seja necessário que cada uma das colunas seja única.
Figura 6.18. Exemplo de Restrição de Unicidade aplicada a um Grupo de Colunas
CREATE TABLE exemplo (
a integer,
b integer,
c integer,
UNIQUE (a, c)
);
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
66
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Além disso, é possível atribuir nomes às restrições de unicidade (Figura 6.19).
Figura 6.19. Exemplo de Restrição de Unicidade em uma Coluna Atribuindo um Nome para a Restrição
CREATE TABLE produtos (
cod_prod integer CONSTRAINT unq_cod_prod UNIQUE,
nome text,
preco numeric
);
3.4. Chaves Primárias
De modo geral, a restrição de chave primária diz respeito à combinação da restrição de unicidade com a restrição de não-
nulo. Desse modo, é possível definir esse tipo de restrição de mais de um modo, conforme apresentado na Figura 6.20.
Figura 6.20. Exemplo de Restrição de Chave Primária versus Restrição de Não-Nulo e Unicidade
1) CREATE TABLE produtos (
cod_prod integer UNIQUE NOT NULL,
nome text,
preco numeric
);
2) CREATE TABLE produtos (
cod_prod integer PRIMARY KEY,
nome text,
preco numeric
);
Por outro lado, as chaves primárias também podem restringir valores em mais de uma coluna (Figura 6.21).
Figura 6.21. Exemplo de Restrição de Chave Primária em Mais de uma Coluna
CREATE TABLE exemplo (
a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
);
3.5. Chaves Estrangeiras
Uma restrição de chave estrangeira procura especificar que o valor de uma coluna, ou mesmo grupo de colunas, corresponda
a algum valor existente em uma linha de outra tabela, de forma a manter a integridade referencial
1
entre duas ou mais
tabelas relacionadas.
1 Integridade Referencial é um conceito de banco de dados que garante que todos os relacionamentos propostos entre tabelas no modelo de entidade-relacionamento (ER) serão
respeitados, dando a certeza que os dados de um banco de dados estarão íntegros.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
67
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
A título de exemplo, tomemos a tabela criada pela sintaxe do segundo item apresentado na Figura 6.20. Adicionalmente,
criemos outra tabela destinada a conter os dados dos pedidos relativos aos produtos. Como existe uma relação entre as
duas tabelas (pedidos e produtos) em que cada pedido precisa conter um ou mais produtos, podemos impor a restrição
de chave-estrangeira para garantir que não sejam incluídos produtos em um pedido que não estejam cadastrados na
tabela produtos (Figura 6.22).
Figura 6.22. Exemplo de Restrição de Chave Estrangeira
CREATE TABLE pedidos (
cod_pedido integer PRIMARY KEY,
cod_prod integer REFERENCES produtos (cod_prod),
quantidade integer
);
No exemplo utilizado, podemos dizer que a tabela de pedidos é a que faz referência, e a tabela de produtos é a referenciada.
Esse tipo de restrição necessita que exista correspondência entre o número e tipo das colunas referenciadas.
Por outro lado, uma tabela também pode conter mais de uma restrição de chave estrangeira, o que é utilizado para
implementar relacionamentos muitos-para-muitos entre tabelas (Figura 6.22). Na Figura 6.23 é exemplificada uma relação
em que a tabela “itens_pedidos” faz referência às tabelas “pedidos” e “produtos” para poder armazenar os dados relativos
a que pedido os itens se referem e que produto deverá constar de cada item.
A partir da restrição imposta, sabemos que a chave estrangeira não permite a criação de pedidos não relacionados com
algum produto. No entanto, é necessário considerar a situação onde um produto seja removido após a criação de um
pedido fazendo referência a esse produto. A linguagem SQL permite tratar essa situação no sentido de que quando se
desejar remover um produto referenciado por um pedido (por meio da tabela itens_pedidos), isso não será permitido, pois
caso um pedido seja removido, os itens do pedido também serão removidos.
Figura 6.23. Exemplo de Restrição de Chave Estrangeira em uma Relação M:M
CREATE TABLE produtos (
cod_prod integer PRIMARY KEY,
nome text,
preco numeric
);
CREATE TABLE pedidos (
cod_pedido integer PRIMARY KEY,
endereco_entrega text,
...
);
CREATE TABLE itens_pedidos (
cod_prod integer REFERENCES produtos,
cod_pedido integer REFERENCES pedidos,
quantidade integer,
PRIMARY KEY (cod_prod, cod_pedido)
);
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
68
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
De forma geral, as opções mais comuns são restringir ou mesmo excluir em cascata (Figura 6.24). O comando RESTRICT,
utilizado para garantir a integridade, também pode ser escrito como NO ACTION, e também é o padrão se nada for
especificado.
Além das opções apresentadas, ainda é possível outras duas opções sobre o que deve acontecer com as colunas da chave
estrangeira quando a chave primária é excluída, SET NULL e SET DEFAULT. Deve ser observado que isso não livra da
obediência às restrições. Por exemplo, se uma ação especificar SET DEFAULT, mas o valor padrão não satisfizer a chave
estrangeira, a exclusão da chave primária não vai ser bem-sucedida.
Semelhante ao comando ON DELETE existe também o comando ON UPDATE, utilizada quando uma coluna referenciada
é atualizada, sendo que as ações possíveis são as mesmas.
Figura 6.24. Exemplo de Restrição e Deleção em Cascata
CREATE TABLE produtos (
cod_prod integer PRIMARY KEY,
nome text,
preco numeric
);
CREATE TABLE pedidos (
cod_pedido integer PRIMARY KEY,
endereco_entrega text,
...
);
CREATE TABLE itens_pedidos (
cod_prod integer REFERENCES produtos ON DELETE RESTRICT,
cod_pedido integer REFERENCES pedidos ON DELETE CASCADE,
quantidade integer,
PRIMARY KEY (cod_prod, cod_pedido)
);
Dica 1: A chave estrangeira deve referenciar colunas de uma chave primária ou de uma restrição de unicidade.
4. Comandos para Alteração de Esquema SQL
Em um banco de dados podem existir vários esquemas e dentro de cada esquema podemos criar várias tabelas. Ao invés
de criar vários bancos de dados, criamos um e criamos esquemas dentro desse. Isso permite uma maior flexibilidade,
pois uma única conexão ao banco permite acessar todos os esquemas e suas tabelas. Portanto, devemos planejar com
eficiência para saber quantos bancos precisaremos, quantos esquemas em cada banco e quantas tabelas em cada esquema.
Cada banco ao ser criado traz um esquema public, que é onde ficam todas as tabelas, caso não seja criado outro esquema.
Esse esquema public não é padrão ANSI. Caso se pretenda ao portável, devemos excluir esse esquema public e criar
outros. Por default todos os usuários criados têm privilégio CREATE e USAGE para o esquema public.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
69
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Um esquema é essencialmente um espaço de nomes: contém objetos com nome (tabelas, tipos de dado, funções e
operadores), cujos nomes podem ser iguais aos de outros objetos existentes em outros esquemas. Os objetos com nome
são acessados “qualificando” seus nomes, usando o nome do esquema como prefixo, ou definindo um caminho de procura
que inclua os esquemas desejados.
Existem diversas razões pelas quais pode-se desejar utilizar esquemas:
• Para permitir vários usuários utilizarem o mesmo banco de dados sem que um interfira no outro.
• Para organizar objetos do banco de dados em grupos lógicos tornando-os mais gerenciáveis.
• Para poder colocar, em esquemas separados, aplicações desenvolvidas por terceiros, de modo a não haver
colisão com nomes de outros objetos.
Os esquemas são análogos aos diretórios no nível do sistema operacional, exceto os esquemas que não podem ser
aninhados.
4.1. Criação de Esquema
A instrução CREATE SCHEMA pode criar um esquema, as tabelas e as exibições contidas e as permissões GRANT,
REVOKE ou DENY em qualquer item protegido em uma única instrução. Deve ser executada como um lote separado
sendo que os objetos gerados por ela são criados diretamente no esquema ativo. As transações CREATE SCHEMA são
atômicas e, caso algum erro ocorra durante a execução da instrução, nenhum item protegido especificado será criado e
nenhuma permissão será concedida.
Os itens protegíveis criados por CREATE SCHEMA podem ser listados em qualquer ordem, com exceção das exibições que
fazem referência a outras exibições. Nesse caso, a exibição mencionada deve ser criada antes da exibição que a menciona.
Portanto, uma instrução GRANT pode conceder permissões em um objeto antes que o objeto propriamente dito seja criado,
ou uma instrução CREATE VIEW pode aparecer antes das instruções CREATE TABLE, que criam as tabelas mencionadas
pela exibição. Além disso, as instruções CREATE TABLE podem declarar chaves estrangeiras definidas posteriormente
na instrução CREATE SCHEMA
A sintaxe do comando é:
CREATE SCHEMA nome_do_esquema [AUTHORIZATION nome_do_usuário ] [elemento_do_esquema [ ... ] ] CREATE
SCHEMA AUTHORIZATION nome_do_usuário [ elemento_do_esquema [ ... ] ]
A Tabela 6.6 apresenta as partes que integram a sintaxe do comando.
Tabela 6.6. Elementos do Comando CREATE SCHEMA
Parte Descrição
Nome_do_esquema O nome do esquema a ser criado. Se for omitido, será usado o nome do usuário
como nome do esquema. O nome não pode começar por pq_, porque esses nomes
são reservados para os esquemas do sistema.
Nome_do_usuário O nome do usuário que será o dono do esquema. Se for omitido, tem como padrão
o usuário que está executando o comando. Somente os superusuários podem criar
esquemas pertencentes a outros usuários.
Elemento_do_esquema Um comando SQL definindo um objeto a ser criado no esquema. Atualmente,
somente CREATE TABLE, CREATE VIEW, CREATE INDEX, CREATE SEQUENCE,
CREATE TRIGGER e GRANT são aceitos como cláusula no comando CREATE
SCHEMA. Os objetos de outros tipos podem ser criados por comando em separado,
após o esquema ter sido criado.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
70
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Na Figura 6.25 é apresentada uma expressão em que é um esquema e uma visão estão mostrando os filmes premiados.
Deve ser observado que os subcomandos individuais não terminam por ponto-e-vírgula.
Figura 6.25. Exemplo de Criação de um Esquema
CREATE SCHEMA cinema
CREATE TABLE filmes (titulo text, lancamento date, premios text[])
CREATE VIEW premiados AS
SELECT titulo, lancamento FROM filmes WHERE premios IS NOT NULL;
Dica 1: As instruções que contêm CREATE SCHEMA AUTHORIZATION, mas não especificam um nome, são
permitidas somente para compatibilidade com versões anteriores.
Dica 2: As instruções CREATE SCHEMA oferecem suporte para DENY e REVOKE. As cláusulas DENY e
REVOKE serão executadas na ordem em que aparecem na instrução CREATE SCHEMA.
4.1.1. Modificando um Esquema
O comando ALTER SCHEMA altera a definição de um esquema. Para utilizar o comando ALTER SCHEMA é necessário
ser o dono do esquema ou ter privilégio para tal. Para mudar o nome do esquema também é necessário possuir o privilégio
CREATE no banco de dados.
Para alterar o dono, também é necessário ser um membro direto ou indireto do novo papel dono, além de possuir o
privilégio CREATE no banco de dados.
A sintaxe do comando é:
ALTER SCHEMA nome_do_esquema RENAME TO novo_nome_do_esquema
ALTER SCHEMA nome_do_esquema OWNER TO nome_do_novo_usuário
Dica 1: Apesar do padrão SQL não possuir esse tipo de recurso, boa parte dos SGBDs já o disponibilizam
como aprimoramento da linguagem.
4.1.2. Removendo um Esquema
O comando DROP SCHEMA objetiva remover esquemas do banco de dados. O esquema somente pode ser removido pelo
seu dono ou por um dba. Deve ser observado que o dono pode remover o esquema (e, portanto, todos os objetos que
esse contém), mesmo que não seja o dono de alguns objetos contidos no esquema.
A sintaxe do comando é:
DROP SCHEMA nome_do_esquema [, ...] [ CASCADE | RESTRICT ]
A opção CASCADE permite que sejam removidos os objetos (tabelas, funções) contidos no esquema, e a opção RESTRICT
permite que seja verificada a existência de algum objeto vinculado ao esquema e impede que o esquema seja removido
quando tem algum conteúdo. Essa é uma opção padrão para a instrução DROP SCHEMA.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
71
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
4.2. O Esquema Público
Na Figura 6.24 o esquema criado recebeu o nome de cinema e os demais componentes (tabela e visão) também foram
nominados. No entanto, caso não fosse indicado um nome para o esquema e para os elementos criados, por padrão, as
tabelas (e outros objetos) seriam colocadas automaticamente em um esquema chamado “public”. Todo banco de dados
novo possui esse esquema. Portanto, poderíamos reescrever o exemplo da Figura 6.25 da seguinte forma (Figura 6.26),
sem qualquer prejuízo quanto à criação do esquema desejado.
Figura 6.26. Exemplo de Criação de um Esquema Public
CREATE SCHEMA
CREATE TABLE filmes (titulo text, lancamento date, premios text[])
CREATE VIEW premiados AS
SELECT titulo, lancamento FROM filmes WHERE premios IS NOT NULL;
Com base no exemplo da Figura 6.26, a tabela “filmes” não seria criada por uma instrução como CREATE TABLE cinema.
filmes e sim como CREATE TABLE public.filmes.
4.3. O Caminho de Procura do Esquema
Os nomes qualificados são desagradáveis de escrever, sendo geralmente melhor não ligar o aplicativo a um esquema
específico. Por isso, geralmente as tabelas são referenciadas por meio de nomes não qualificados, formados apenas pelo
nome da tabela. O sistema determina que tabela está sendo referenciada seguindo o caminho de procura, que é uma lista
de esquemas para procura. A primeira tabela correspondente encontrada no caminho de procura é assumida como sendo
a desejada. Não havendo nenhuma correspondência no caminho de procura é relatado um erro, mesmo que uma tabela
correspondendo ao nome exista em outro esquema no banco de dados.
O primeiro nome de esquema no caminho de procura é chamado de esquema corrente. Além de ser o primeiro esquema a
ser procurado, também é o esquema onde as novas tabelas são criadas quando o comando CREATE TABLE não especifica
o nome do esquema.
A sintaxe para mostrar o caminho de procura corrente é:
SHOW search_path
O retorno obtido pelo comando, na situação padrão é:
a) Search path
b) $user,public
O primeiro elemento especifica que deve ser procurado o esquema com o mesmo nome do usuário corrente. Se esse
esquema não existir, essa entrada será ignorada. O segundo elemento se refere ao esquema público visto anteriormente.
O primeiro esquema existente do caminho de procura é o local padrão para a criação dos novos objetos. Essa é a razão
pela qual, por padrão, os objetos são criados no esquema público. Quando os objetos são referenciados em qualquer outro
contexto sem qualificação pelo esquema (comandos de modificação de tabelas, modificação de dados ou consultas) o
caminho de procura é percorrido até que o objeto correspondente seja encontrado. Portanto, na configuração padrão,
qualquer acesso não qualificado somente pode fazer referência ao esquema público.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
72
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
4.4. Esquemas e Privilégios
Por padrão, os usuários não podem acessar objetos em esquemas que não são seus. Para poderem acessá-los, o dono
do esquema precisa conceder o privilégio USAGE para o esquema. Para permitir os usuários utilizarem os objetos do
esquema é necessário conceder privilégios adicionais, conforme seja apropriado para cada objeto.
Pode ser permitido, também, que um usuário crie objetos no esquema de outro usuário. Para permitir que isso seja feito,
deve ser concedido o privilégio CREATE para o esquema. Deve ser observado que, por padrão, todos os usuários possuem
o privilégio CREATE e USAGE para o esquema public. Isso permite a todos os usuários que podem se conectar ao banco
de dados criarem objetos no esquema public.
Se isso não for desejado, esse privilégio poderá ser revogado, utilizando a seguinte sintaxe:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
O primeiro “public” no comando acima é o nome do esquema, enquanto o segundo “public” significa “todos os usuários”.
Na primeira ocorrência é um identificador, enquanto que na segunda ocorrência é uma palavra-chave; por isso, na primeira
vez está escrito em minúsculas, enquanto que, na segunda vez, em maiúsculas.
4.5. O Esquema do Catálogo do Sistema
Além do esquema public e dos esquemas criados pelos usuários, cada banco de dados inclui o esquema contendo as
tabelas do sistema e todos os tipos de dados, funções e operadores nativos (nome do esquema pode variar de acordo com
o SGBD). Esse catálogo é sempre parte efetiva do caminho de procura. Se não for colocado explicitamente no caminho
de procura, então será procurado implicitamente antes dos esquemas do caminho de procura. Isso garante que os nomes
nativos sempre possam ser encontrados. Entretanto, é possível colocar explicitamente o nome do catálogo no final do
caminho de procura, se for desejado que os nomes definidos pelo usuário substituam os nomes nativos.
4.6. Modelos de Utilização
Os esquemas podem ser utilizados para organizar os dados de várias maneiras. Existem uns poucos modelos de utilização
recomendados, facilmente suportados pela configuração padrão:
• Se não for criado nenhum esquema, então todos os usuários acessarão o esquema público implicitamente,
simulando a situação onde os esquemas não estão disponíveis. Essa configuração é recomendada,
principalmente, quando existe no banco de dados apenas um usuário, ou alguns poucos usuários colaborativos.
Essa configuração também permite uma transição suave de uma situação sem esquemas.
• Pode ser criado um esquema para cada usuário com o mesmo nome do usuário. Lembre-se que o caminho de
procura padrão começa por $user, que é resolvido como o nome do usuário. Portanto, se cada usuário possuir
um esquema separado, vão acessar seus próprios esquemas por padrão.
• Se essa configuração for utilizada, também poderá ser revogado o acesso ao esquema público (ou mesmo
removê-lo), deixando os usuários totalmente restritos aos seus próprios esquemas.
• Para instalar aplicações compartilhadas (tabelas utilizadas por todos, funções adicionais fornecidas por
terceiros), essas devem ser colocadas em esquemas separados. Devem ser concedidos, também, os privilégios
necessários para permitir o acesso pelos outros usuários. Os usuários poderão, então, fazer referência a
esses objetos adicionais qualificando seus nomes com o nome do esquema, ou poderão adicionar esquemas
ao caminho de procura, conforme julgarem melhor.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
73
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
4.7. Portabilidade
No padrão SQL, não existe a noção de objetos no mesmo esquema pertencendo a usuários diferentes. Além disso, algumas
implementações não permitem criar esquemas com nome diferente do nome de seu dono. Na verdade, os conceitos de
esquema e de usuário são praticamente equivalentes em sistemas de banco de dados que implementam somente o suporte
básico a esquemas especificado no padrão. Portanto, muitos usuários consideram os nomes qualificados na verdade
formados por nome_do_usuário.nome_da_tabela.
Obviamente, alguns sistemas de banco de dados SQL podem não implementar esquemas de nenhuma maneira, ou oferecer
suporte a espaços de nomes, permitindo apenas acesso entre bancos de dados. Se for necessário trabalhar com esses
sistemas, será obtido o máximo de portabilidade, não utilizando nada relacionado a esquemas.
5. Consultas em SQL
Uma consulta expressa em uma linguagem de consulta de alto nível, como a SQL, deve primeiramente ser examinada,
analisada e validada. O examinador identifica os símbolos da linguagem – como por exemplo palavras chaves da SQL,
nomes de atributos e nomes de relações – no texto de consulta, enquanto o analisador verifica a sintaxe de consulta para
determinar se ela está formulada de acordo com as regras de sintaxe (regras de gramática) da linguagem de consulta.
Além disso, a consulta também deve ser validada, verificando se todos os nomes de atributos e relações são válidos e
semanticamente significativos no esquema do banco de dados específico que está sendo consultado. Uma representação
interna da consulta é, então, criada, geralmente em forma de uma estrutura de dados de árvore
1
, denominada árvore de
consulta. Também é possível representar a consulta utilizando-se de uma estrutura gráfica de dados denominada gráfico
de consulta. O SGBD deve então planejar uma estratégia de execução para recuperar o resultado da consulta, a partir dos
arquivos de banco de dados. Uma consulta geralmente tem muitas estratégias de execução e o processamento utilizado
para escolher uma estratégia que seja adequada para processar uma consulta é conhecido como otimização de consulta
5.1. O comando SELECT
O comando select permite a seleção de tuplas e atributos em uma ou mais tabelas. A sintaxe básica para o uso do
comando select é:
SELECT [atributo] { * | tabela.* | [tabela.]campo1 [AS alias1] [, [tabela.]campo2 [AS alias2] [, ...]]}
FROM expressãodetabela [, ...] [IN bancodedadosexterno]
[WHERE... ]
[GROUP BY... ]
[HAVING... ]
[ORDER BY... ]
[WITH OWNERACCESS OPTION]
A Tabela 6.7 apresenta as partes que integram a sintaxe do comando.
1 Árvore é uma estrutura de dados que herda as características das topologias em árvore. Conceitualmente difere das listas encadeadas, em que os dados se encontram numa
sequência, pelo fato dos dados estarem dispostos de forma hierárquica.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
74
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Tabela 6.7. Elementos do Comando SELECT
Parte Descrição
Atributo
Um dos atributos a seguir: ALL, DISTINCT, DISTINCTROW ou TOP. Você utiliza
o atributo para restringir o número de registros retornados. Se nenhum for
especificado, o padrão será ALL.
*
Especifica que todos os campos da tabela ou tabelas especificadas estão
selecionados.
tabela
O nomde da tabela contendo os campos a partir dos quais os registros são
selecionados.
campo1, campo2
Os nomes dos campos contendo os dados que você deseja recuperar. Se você
incluir mais de um campo, eles serão recuperados na ordem listada.
alias1, alias2
Os nomes a serem utilizados como cabeçalhos de coluna em lugar dos nomes
originais de coluna em tabela.
expressãodetabela O nome da tabela ou tabelas contendo os dados que você deseja recuperar.
bancodedadosexternos
O nome do banco de dados que contém as tabelas em expressão de tabela se elas
não estiverem no banco de dados atual.
Por exemplo, suponhamos que estamos trabalhando com um banco de dados onde existe o cadastro de pessoal de uma
empresa. Nesse caso, para selecionar o nome e o RG dos funcionários que trabalham no departamento número 2, na
tabela EMPREGADOS utilizamos o seguinte comando:
SELECT nome, rg
FROM EMPREGADOS
WHERE depto = 2;
O resultado obtido com a consulta, então, é o seguinte:
Nome RG
Fernando 20202020
Ricardo 30303030
Jorge 40404040
Na linguagem em SQL também é permitido o uso de condições múltiplas, conforme o seguinte exemplo:
SELECT nome, rg, salario
FROM EMPREGADOS
WHERE depto = 2 AND salario > 2500.00;
O resultado obtido com a consulta, então, é o seguinte:
Nome RG Salário
Jorge 40404040 4.200,00
A instrução que envolver as cláusulas SELECT-FROM-WHERE em SQL permite envolver quantas tabelas forem necessárias.
Tomemos como exemplo a situação em que desejamos selecionar o número do departamento que controla projetos
localizados em Brasília. Para tanto, podemos utilizar o seguinte comando:
SELECT t1.numero_depto
FROM departamento_projeto t1, projeto t2
WHERE t1.numero_projeto = t2.numero;
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
75
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Na expressão anterior, t1 e t2 são chamados “alias” (apelidos) e representam a mesma tabela a qual estão referenciando.
Um “alias” é muito importante quando há redundância nos nomes das colunas de duas ou mais tabelas que estão envolvidas
em uma expressão. Ao invés de utilizar o “alias”, também é possível utilizar o nome da tabela, mas isso pode se tornar
muito trabalhoso em consultas muito complexas, além do que impossibilitaria a utilização da mesma tabela mais que
uma vez em uma expressão SQL.
Suponhamos que desejamos selecionar o nome e o RG de todos os funcionários que são supervisores. Para tanto, podemos
utilizar o seguinte comando:
SELECT e1.nome, e1.rg
FROM empregado e1, empregado e2
WHERE e1.rg = e2.rg_supervisor;
O resultado obtido com a consulta, então, é o seguinte:
Nome RG
João Luiz 10101010
Fernando 20202020
A utilização do operador * dentro do especificador SELECT permite selecionar todos os atributos de uma tabela, enquanto
que a exclusão do especificador WHERE faz com que todas as tuplas de uma tabela sejam selecionadas. Vejamos o
comando apresentado a seguir:
SELECT *
FROM empregados;
O resultado obtido com a consulta, então, é:
Nome RG CPF Depto. RG Supervisor Salário
João Luiz 10101010 11111111 1 NULO 3.000,00
Fernando 20202020 22222222 2 10101010 2.500,00
Ricardo 30303030 33333333 2 10101010 2.300,00
Jorge 40404040 44444444 2 20202020 4.200,00
Renato 50505050 55555555 3 20202020 1.300,00
Um ponto importante a considerar é que a operação SELECT em SQL permite a geração de tuplas duplicadas como resultado
de uma expressão. Para evitar isto, é necessário utilizar o especificador DISTINCT. Suponhamos o seguinte exemplo:
SELECT depto FROM empregado;
O resultado obtido com a consulta, então, é o seguinte:
Depto.
1
2
2
2
3
No entanto, veja o mesmo exemplo com o especificador DISTINCT.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
76
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
SELECT DISTINCT depto FROM empregado;
Depto.
1
2
3
Outra possibilidade da linguagem SQL é a geração de consultas aninhadas utilizando o especificador IN, que permite
que seja feita uma comparação do especificador WHERE da consulta mais externa com o resultado da consulta mais
interna. Suponhamos que desejamos selecionar o nome de todos os funcionários que trabalham em projetos localizados
em Brasília. O comando a ser utilizado será:
SELECT e1.nome, e1.rg, e1.depto FROM empregado e1, empregado_projeto e2 WHERE e1.rg = e2.rg_empregado
AND e2.numero_projeto IN (select numero FROM projeto WHERE localizacao = ‘Brasília‘);
Caso seja necessário selecionar um conjunto de tuplas de forma ordenada devemos utilizar o comando ORDER BY.
Suponhamos que desejamos selecionar todos os empregados por ordem alfabética. O comando a ser utilizado será:
SELECT nome, rg, depto
FROM empregado
ORDER BY nome;
6. Comandos INSERT, DELETE e UPDATE em SQL
6.1. O comando INSERT
O comando INSERT objetiva inserir novas linhas na tabela. Podem ser inseridas uma ou mais linhas especificadas por
expressões de valor, ou zero ou mais linhas resultantes de uma consulta.
Os nomes das colunas de destino podem ser listados em qualquer ordem sendo que quando não é fornecida nenhuma lista
de nomes de colunas, o padrão é usar todas as colunas da tabela na ordem em que foram declaradas; ou os primeiros N
nomes de colunas, se existirem apenas N colunas fornecidas na cláusula VALUES ou na consulta. Os valores fornecidos
pela cláusula VALUES ou pela consulta são associados à lista de colunas explícita ou implícita da esquerda para a direita.
As colunas que não estão presentes na lista de colunas explícita ou implícita são preenchidas com o valor padrão, seja
o valor padrão declarado ou nulo se não houver nenhum.
Se a expressão para alguma coluna não for do tipo de dado correto, será tentada uma conversão de tipo automática.
A cláusula opcional RETURNING faz com que o comando INSERT compute e retorne valores baseados em cada linha
realmente inserida. Sua utilidade principal é obter valores fornecidos por padrão, como o número sequencial de uma
coluna serial. Entretanto, é permitida qualquer expressão que utilize as colunas da tabela. A sintaxe da lista RETURNING
é idêntica à da lista de saída do comando SELECT. Além disso, é necessário possuir o privilégio INSERT na tabela para
poder inserir linhas, e o privilégio SELECT para utilizar RETURNING. Se for utilizada a cláusula consulta para inserir linhas
a partir de uma consulta, também será necessário possuir o privilégio SELECT em todas as tabelas usadas pela consulta.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
77
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
A sintaxe geral para o comando INSERT INTO é:
INSERT INTO destino [IN bancodedadosexterno] [(campo1[, campo2[, ...]])] SELECT [origem.]campo1[, campo2[, ...]
FROM expressãodetabela
Suponhamos que desejamos inserir os seguintes dados:
nome: Jorge Gonçalves
rg: 60606060
cic: 66666666
departamento: 3
rg_supervisor: 20202020
salário: R$ 4.000,00
O comando a ser utilizado será:
INSERT INTO empregados
VALUES (‘Jorge Goncalves’, ‘60606060’, ‘66666666’, 3, ‘20202020’, 4000,00);
Como nesse exemplo, todos os campos foram inseridos, não é necessário especificar o nome das colunas na sintaxe.
Suponhamos que desejamos agora inserir os seguintes dados:
nome: Joao de Campos
rg: 70707070
cic: 77777777
departamento: 3
salário: R$2.500,00
INSERT INTO empregados (nome, rg, cic, depto, salario)
VALUES (‘Joao de Campos, ‘70707070’, ‘77777777’, 3, 2500,00);
A Tabela 6.8 apresenta as partes que integram a sintaxe do comando.
Tabela 6.8. Elementos do Comando INSERT
Parte Descrição
destino O nome da tabela ou consulta é qual acrescentar os registros.
bancodedadosexterno0
O caminho até um banco de dados externo. Para obter uma descrição do caminho,
consulte a cláusula IN.
origem O nome da tabela ou consulta a partir da qual os registros vão ser copiados.
campo1, campo2
Nomes do campos aos quais os dados serão acrecentados, se se seguirem a um
argumento destino, ou os nomes dos campos a partir dos quais os dados serão
obtidos, se se seguirem a um argumento origem.
Expressãodetabela
O nome da tabela ou das tabelas das quais os registros são inseridos. Esse
argumento pode ser um nome de tabela simples ou um composto resultante de
uma operação INNER JOIN, LEFT JOIN ou RIGHT JOIN ou uma consulta salva.
valor1, valor2
Os valores a serem inseridos nos campos específicos do novo registro. Cada valor
é inserido no campo que corresponde à posição do valor na lista: valor1 é inserido
no campo1 do novo registro, valor 2 no campo2, e assim por diante. Você deve
separar os valores com uma vírgula e colocar os campos de texto entre aspas (“ “)
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
78
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
Nesse exemplo, como o campo rg_supervisor não foi inserido, foi necessário especificar as colunas que deveriam receber
dados. Outra forma de se elaborar essa inserção seria:
INSERT INTO empregados
VALUES (‘Joao de Campos, ‘70707070’, ‘77777777’, 3, ‘’, 2500,00);
Nessa situação utilizaram-se os caracteres ‘’ para se declarar que um valor nulo seria inserido nesta coluna, o que dispensa
a necessidade e se especificar as colunas.”
6.2. O comando UPDATE
A modificação dos dados armazenados no banco de dados é referida como atualização. Pode ser atualizada uma linha da
tabela, todas as linhas da tabela, ou um subconjunto das linhas. Cada coluna pode ser atualizada individualmente, não
afetando as outras colunas.
A sintaxe geral para o comando UPDATE é:
UPDATE tabela SET novovalor WHERE critérios
A Tabela 6.9 apresenta as partes que integram a sintaxe do comando.
Tabela 6.9. Elementos do Comando UPDATE.
Parte Descrição
tabela O nome da tabela contendo os dados que você quer modificar.
Novovalor
Uma expressão que determina o valor a ser inserido em um campo específico dos
registros atualizados.
critérios
Uma expressão que determina quais registros serão atualizados. Apenas os
registros que satisfazem à expressão são atualizados.
Suponhamos que desejamos agora atualizar os dados relativos ao salário de todos os empregados que trabalham no
departamento 2 para R$ 3.000,00. O comando a ser utilizado será:
UPDATE empregado SET salario = 3.000,00 WHERE depto = 2;
Caso a cláusula WHERE seja omitida, todas as linhas da tabela serão atualizadas. Quando está presente, apenas as
linhas atendendo a condição escrita após o WHERE serão atualizadas. Observe que o sinal de igual na cláusula SET é
uma atribuição, enquanto o sinal de igual na cláusula WHERE é uma comparação, mas isto não causa ambiguidade
Dica 1: O comando UPDATE não gera um conjunto de resultados. Além disso, depois de atualizar os registros
usando uma consulta de atualização, você não poderá desfazer a operação. Se quiser saber quais os registros
que foram atualizados, examine antes os resultados de uma consulta seleção que usem os mesmos critérios e,
depois, execute a consulta de atualização. Mantenha sempre cópias de backup dos dados. Se você atualizar
os registros errados, poderá recuperá-los a partir das cópias.
6.3. O comando DELETE
O comando DELETE permite que seja excluída uma ou mais linhas de uma tabela. Assim como só é possível adicionar
dados para toda uma linha, também uma linha só pode ser removida por completo de uma tabela. Se for necessário excluir
valores de um campo específico, basta criar uma consulta atualização que altere os valores para Null.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
79
Sistemas de Banco de Dados: conceitos e arquiteturas Unidade II
A linguagem SQL não oferece funcionalidade para endereçar diretamente linhas específicas. Portanto, a remoção de linhas
só pode ser feita por meio da especificação das condições que as linhas a serem removidas devem atender. Referenciando
uma chave primária na tabela, então, é possível especificar exatamente a linha. Porém, também pode ser removido um
grupo de linhas, atendendo a uma determinada condição, ou podem ser removidas todas as linhas da tabela de uma só vez.
A sintaxe geral para o comando DELETE é:
DELETE [tabela.*] FROM tabela WHERE critérios
A Tabela 6.10 apresenta as partes que integram a sintaxe do comando.
Tabela 6.10. Elementos do Comando DELETE
Parte Descrição
tabela.* O nome opcional da tabela da qual são excluídos registros.
tabela O nome da tabela da qual são excluídos registros.
Critérios Uma expressão que determina os registros a ser excluídos
Suponhamos que desejamos agora excluir os dados relativos aos registros nos quais o empregado trabalhe no departamento
2 e possua salário maior que R$ 3.500,00. O comando a ser utilizado será:
DELETE FROM empregado WHERE salario > 3.500,00 AND depto = 2;
A função DELETE é especialmente útil quando se deseja excluir muitos registros pois, para excluir uma tabela inteira do
banco de dados, é possível usar o método Execute com uma instrução DROP, o que resulta na exclusão dos dados e da
estrutura da tabela. Em contrapartida, ao utilizar o comando DELETE, somente os dados são excluídos e a estrutura da
tabela e todas as suas propriedades, como atributos de campo e índices, permanecem intactos.
É possível utilizar o comando DELETE para remover registros de tabelas que estão em um relacionamento um-paramuitos
com outras tabelas. As operações de exclusão em cascata fazem com que os registros em tabelas que estão no lado
muitos do relacionamento sejam excluídos quando o registro correspondente no lado um do relacionamento é excluído
na consulta.

Dica 1: Depois de remover os registros utilizando uma consulta exclusão, você não poderá desfazer a operação.
Se quiser saber quais registros foram excluídos, examine antes os resultados de uma consulta seleção que
use os mesmos critérios e, depois, execute a consulta exclusão.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
81
Capítulo 7 – Dependência Funcional e Normalização
1. Dependência Funcional
Dependência Funcional diz respeito a uma restrição entre dois conjuntos de atributos de uma base de dados. Também
pode ser vista como um conjunto de restrições ao conjunto de relações válidas. Suponha que o esquema de uma base
de dados R possua n atributos A
1
, A
2
,..., A
n
e considere que em R = { A
1
, A
2
, ... , A
n
} como a representação universal
da base de dados.
Uma dependência funcional, representada por X ¬ Y entre dois conjuntos de atributos X e Y que são subconjuntos de R
especificam uma restrição nas tuplas que podem compor uma instância relação r de R. A restrição estabelece que para
qualquer par de tuplas t
1
e t
2
em r de forma que t
1
.[X] = t
2
.[X], é obrigado a existir t
1
.[Y] = t
2
.[Y]. Isto significa que os
valores do componente Y em uma tupla em r dependem de, ou são determinados pelos valores do componente X.
Para X ¬ Y lê-se: Y é funcionalmente dependente de X, ou X infere sobre Y.
Suponhamos o seguinte exemplo de dependências funcionais:
a. RG ¬ { Nome, CPF, Depto., RG_Supervisor, Salário}
b. Número_Projeto ¬ { Nome_Projeto, Localização}
c. { RG_Empregado, Número_Projeto } ¬ Horas
A dependência (a) implica que o número de um RG define de forma única o nome do empregado e o seu CPF do empregado.
A dependência (b) implica que o número do projeto define de forma única o nome do projeto e sua localização e a
dependência (c) implica que o RG do empregado mais o número do projeto define de forma única o número de horas
que o empregado trabalhou no projeto.
Em outras palavras, uma dependência funcional pode ser vista como uma propriedade do significado ou semântica dos
atributos em um esquema de relação R. Utiliza-se o entendimento da semântica de atributos de R – isto é, como eles
se relacionam – para especificar as dependências funcionais envolvidas em todas as instâncias da relação r (extensão)
de R. As instâncias r que satisfazem as restrições de dependência funcional especificadas sobre atributos de R são
chamadas extensões legais, pois obedecem as restrições de dependência funcional. Assim, a principal utilização das
dependências funcionais é a de descrever um esquema de relação R, especificando restrições sobre seus atributos, que
devem ser válidas todas as vezes.
A especificação das inferências deve ser elaborada pelo projetista de banco de dados em conjunto com o analista de
sistemas, pois eles deverão ter conhecimento da semântica da base de dados.
Unidade III
Teoria e Metodologia do Projeto de
Banco de Dados
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
82
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Analisando o conceito de dependência funcional, podemos identificar algumas variações.
a) Dependência funcional total: Numa relação R, o atributo y é funcionalmente dependente total de x (x,
y Î R), no caso de x ser um atributo composto, se, e apenas se, é funcionalmente dependente de x e não é
funcionalmente dependente de qualquer subconjunto dos atributos de x.
b) Dependência funcional parcial: Uma dependência funcional parcial é uma dependência funcional X Y
se existir um atributo A qualquer do componente X que pode ser removido e a dependência funcional X
Y não deixa de existir.
c) Dependência funcional transitória: Uma dependência funcional R: x _ y é transitória, se existe um
atributo z que não é um subconjunto de x, tal que x _ z e z _ y.
d) Dependência funcional multivalor: Uma dependência multivalor só se verifica nos casos em que a relação
tem pelo menos 3 atributos _ Numa relação R, o atributo y tem uma dependência funcional multivalor
relativamente a x (x, y Î R), se para cada par de tuplas de R contendo os mesmos valores de x, também
existe um par de tuplas de R correspondentes à troca dos valores de y no par original.
1.1. Normalização
O processo de normalização pode ser visto como o processo no qual são eliminados esquemas de relações (tabelas) não
satisfatórios, decompondo-os, por meio da separação de seus atributos em esquemas de relações menos complexas, mas
que satisfaçam as propriedades desejadas.
O processo de normalização, proposto inicialmente por Codd (1972), conduz um esquema de relação por meio de conjunto
de testes para certificar se o ele está na 1
a
, 2
a
e 3
a
Formas Normais. Essas três Formas Normais são baseadas em
dependências funcionais dos atributos do esquema de relação.
1.1.1. Primeira Forma Normal
A 1
a
Forma Normal pressupõe que todos os atributos de uma tabela devem ser atômicos, ou seja, não são permitidos
atributos multivalorados, atributos compostos ou atributos multivalorados compostos. Consideremos o seguinte exemplo:
• CLIENTE
1. Código
2. {Telefone}
3. Endereço: (Rua, Número, Cidade)
A Tabela 7.1 apresenta uma estrutura para armazenar os dados do exemplo.
Tabela 7.1. Representação da tabela Cliente
Cliente Código
Telefone 1 Endereço
Telefone n Rua N
o
Cidade
Considerando os pressupostos da 1
a
Forma Normal, é necessário reestruturar a Tabela 7.1, pois seus atributos não são
atômicos. Para que a Tabela 7.1 atenda aos pressupostos da 1a Forma Normal temos que eliminar os atributos não
atômicos. O resultado é a geração das Tabelas 7.1a e 7.1b.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
83
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Tabela 7.1a. Representação da tabela Cliente normalizada (1ª FN)
Cliente Código Rua No Cidade
Tabela 7.1b. Representação da tabela Cliente normalizada (1ª FN)
Cliente_Telefone Código_Cliente Telefone_Cliente
1.1.2. Segunda Forma Normal
A 2ª Forma Normal baseia-se no conceito da dependência funcional total. Conforme mencionamos anteriormente,
uma dependência funcional X ¬ Y é total se removemos um atributo A qualquer do componente X e, desta forma, a
dependência funcional deixa de existir.
Tomemos como exemplo, a dependência funcional (c) mencionada no item 7.1.
(c) {RG_Empregado, Número_Projeto} ¬ Horas
Podemos dizer que se trata de uma dependência funcional total, pois se removermos o atributo RG_Empregado ou o
atributo Número_Projeto, a dependência funcional deixa de existir.
Desse modo, podemos dizer que uma tabela T atende à 2ª Forma Normal se estiver na 1ª Forma Normal e todo atributo que
não compõem a chave primária C for em sua totalidade funcionalmente dependente da chave primária C. Se uma tabela
não está na 2ª Forma Normal, ela pode ser normalizada gerando outras tabelas cujos atributos que não façam parte da
chave primária sejam funcionalmente dependentes dela em sua totalidade, passando, assim, a assumir a 2ª Forma Normal.
1.1.3. Terceira Forma Normal
A 3ª Forma Normal, por sua vez, baseia-se no conceito de dependência transitória. Como apresentado anteriormente,
uma dependência funcional transitória e uma dependência funcional X ¬ Y em uma tabela T se existir um conjunto de
atributos Z que não é um subconjunto de chaves de T e as dependências X ¬ Z, Z ¬ Y, são válidas.
Consideremos o seguinte exemplo:
Tabela 7.2a. Representação da Tabela Empregado
Empregado RG Nome No_Departamento Nome_Depto RG_Ger_Depto
Analisando a Tabela 7.2a, temos a seguinte dependência transitiva:
a. RG ¬{Nome_Depto, RG_Ger_Depto}
b. RG ¬ No_Departamento
c. No_Departamento ¬ {Nome_Depto, RG_Ger_Depto}
Analisando a Tabela 7.2a, temos a seguinte dependência transitiva:
Tabela 7.2b. Representação da Tabela Empregado
Empregado RG CPF Nome No_Funcional
d. RG ¬ {Nome, No_Funcional}
e. RG ¬ CPF
f. CIC ¬ {Nome, No_Funcional}
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
84
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Conforme pode ser visto na Tabela 7.2b, o CPF, por ser naturalmente um identificador do empregado, pode ser encarado
como uma chave-candidata.
Uma tabela está na 3
a
Forma Normal se estiver na 2
a
Forma Normal e não houver dependência transitiva entre atributos
não chave.
2. A Álgebra Relacional
A Álgebra Relacional é uma coleção de operações canônicas que são utilizadas para manipular as relações. Segundo
Silberschatz (2006), a Álgebra Relacional é um conjunto de operadores que tomam relações como seus operandos e
retorna uma relação como seu resultado.
Essas operações são utilizadas para selecionar tuplas de relações individuais e para combinar tuplas relacionadas de
relações diferentes para especificar uma consulta em um determinado banco de dados. O resultado de cada operação é
uma nova operação, a qual também pode ser manipulada pela álgebra relacional.
Algumas aplicações da álgebra relacional são:
• Definir um escopo para busca.
• Definir um escopo para atualização (dados inseridos, alterados ou eliminados).
• Definir restrições de integridade (definir restrição ao qual o BD deverá obedecer).
• Definir variáveis de relações derivadas (visões e snapshots).
• Definir requisitos de segurança (definir os dados sobre os quais será concedida alguma espécie de autorização).
2.1. A Operação SELECT
A operação SELECT é utilizada para selecionar um subconjunto de tuplas de uma relação, sendo que essas tuplas devem
satisfazer uma condição de seleção. A forma geral de uma operação SELECT é:
c
<condição de seleção>

( <nome da relação> )
A letra grega c é utilizada para representar a operação de seleção; <condição de seleção> é uma expressão booleana
aplicada sobre os atributos da relação e <nome da relação> é o nome da relação sobre a qual será aplicada a
operação SELECT.
Exemplificando, tomemos a seguinte expressão:
Consulta
1
= c
salário < 2.500,00
(EMPREGADO)
A partir da expressão da consulta
1
, teremos os seguintes resultados:
Tabela 7.3. Tabela com resultados da Consulta
1
Nome RG CIC Depto. RG Supervisor Salário
Ricardo 30303030 33333333 2 10101010 2.300,00
Renato 50505050 55555555 3 20202020 1.300,00
Tomemos agora a expressão:
Consulta
2
= c
(relação = “Filho”) .AND. (sexo = “Feminino”)

(DEPENDENTES)
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
85
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
A partir da expressão da consulta
2
, teremos os seguintes resultados:
Tabela 7.4. Tabela com resultados da Consulta
2
RG Responsável Nome Dependente Dt. Nascimento Relação Sexo
30303030 Adreia 01/05/90 Filho Feminino
Os operadores relacionais que podem ser aplicadas na operação SELECT são: <, >, ±, ±, =, = além dos operadores
booleanos: and, or, not.
A operação select é unária, ou seja, só pode ser aplicada a uma única relação. Não é possível aplicar a operação sobre
tuplas de relações distintas.
2.2. A Operação PROJECT
A operação PROJECT seleciona um conjunto determinado de colunas de uma relação. A forma geral de uma operação
PROJECT é:
¬
<lista de atributos>
(<nome da relação>)
A letra grega ¬ representa a operação PROJECT, <lista de atributos> representa a lista de atributos que o usuário
deseja selecionar e <nome da relação> representa a relação sobre a qual a operação PROJECT será aplicada.
Exemplificando, tomemos a seguinte expressão:
Consulta
3
= ¬
Nome, Dt. Nascimento

(DEPENDENTES)
A partir da expressão da consulta
3,
teremos os seguintes resultados:
Tabela 7.5. Tabela com resultados da Consulta
3
Nome Dependente Dt. Nascimento
Jorge 27/12/86
Luiz 18/11/79
Fernanda 14/02/69
Angelo 10/02/95
Adreia 01/05/90
2.3. Seqüencialidade de Operações
As operações PROJECT e SELECT podem ser utilizadas de forma combinada, permitindo que apenas determinadas
colunas de determinadas tuplas possam ser selecionadas.
A forma geral de uma operação sequencializada é:
¬
<lista de atributos>
(c
<condição de seleção>

(<nome da relação>)
)
Exemplificando, tomemos a seguinte expressão:
Consulta
4
= ¬
nome, depto., salario
(c
salario < 2.500,00
(EMPREGADO)
)
A partir da expressão da Consulta
4,
teremos os seguintes resultados:
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
86
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Tabela 7.6. Tabela com resultados da Consulta
4
Nome Depto. Salário
Ricardo 2 2.300,00
Renato 3 1.300,00
Por outro lado, a Consulta
4
pode ser reescrita em duas outras expressões.
a) Consulta
5
= c
salario < 2.500,00
(EMPREGADO)
A partir da expressão da consulta
5
teremos os seguintes resultados:
Tabela 7.7a. Tabela com resultados da Consulta
5
Nome RG CPF Depto. RG Supervisor Salário
Ricardo 30303030 33333333 2 10101010 2.300,00
Renato 50505050 55555555 3 20202020 1.300,00
b) Consulta
6
= ¬
nome, depto., salario
(CONSULTA
5
)
A partir da expressão da Consulta
6,
teremos os seguintes resultados:
Tabela 7.7b. Tabela com resultados da Consulta
6
Nome Depto. Salário
Ricardo 2 2.300,00
Renato 3 1.300,00
Como pode ser visto nas Tabelas 7.7a e 7.7b, o resultado das consultas acaba sendo o mesmo, porém é mais simples
utilizar a forma descrita na Consulta
4
.
2.4. Operações Matemáticas
Levando em consideração que as relações podem ser tratadas como conjuntos, podemos então aplicar um conjunto de
operações matemáticas sobre elas. Essas operações são: união (L) , intersecção (ì) e diferença (-).
Esse conjunto de operações não é unário, ou seja, pode ser aplicado sobre mais de uma tabela, porém, existe a necessidade
de as tabelas possuírem tuplas exatamente do mesmo tipo.
Essas operações apresentam as seguintes características.
• União – operação representada por R L S, tem como resultado: uma relação T, que inclui todas as tuplas
que se encontram em R e todas as tuplas que se encontram em S.
• Intersecção – operação representada por R ì S, tem como resultado uma relação T, que inclui as tuplas
que se encontram em R e em S ao mesmo tempo.
• Diferença – operação representada por R - S, tem como resultado uma relação T, que inclui todas as tuplas
que estão em R, mas não estão em S.
Suponhamos que uma consulta deseja selecionar todos os empregados que trabalham no departamento número 2 ou que
supervisionam empregados que trabalham no departamento número 2.
Em primeiro lugar, vamos primeiro selecionar todos os funcionários que trabalham no departamento número 2. Para
tanto, utilizaremos a seguinte expressão:
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
87
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Consulta
7
= c
depto = 2
(EMPREGADOS)
A partir da expressão da Consulta
7,
teremos os seguintes resultados:
Tabela 7.8a. Tabela com resultados da Consulta
7
Nome RG CPF Depto. RG Supervisor Salário
Fernando 20202020 22222222 2 10101010 2.500,00
Ricardo 30303030 33333333 2 10101010 2.300,00
Jorge 40404040 44444444 2 20202020 4.200,00
Em seguida, selecionaremos os supervisores dos empregados que trabalham no departamento número 2, utilizando a
seguinte expressão:
Consulta
8
= ¬
rg_supervisor

(CONSULTA
7
)
A partir da expressão da Consulta
8
, teremos os seguintes resultados:
Tabela 7.8b. Tabela com resultados da Consulta
8
RG Supervisor
10101010
20202020
Com base na Consulta
7
, vamos buscar apenas o rg dos empregados selecionados, com base na seguinte expressão:
Consulta
9
= ¬
rg
(CONSULTA
7
)
A partir da expressão da Consulta
9
, teremos os seguintes resultados:
Tabela 7.8c. Tabela com resultados da Consulta
9
RG
20202020
30303030
40404040
Por fim, necessitamos unir as Tabelas 7.8b e 7.8c, obtendo o resultado final.
Consulta
10
= CONSULTA
8
L CONSULTA
9
A partir da expressão da Consulta
10
, teremos os seguintes resultados:
Tabela 7.8d. Tabela com resultados da Consulta
10
RG
20202020
30303030
40404040
10101010
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
88
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
2.5. Produto Cartesiano
O produto cartesiano é uma operação binária que combina todas as tuplas de duas tabelas. Diferente da operação união,
o produto cartesiano não exige que as tuplas das tabelas possuam exatamente o mesmo tipo. O produto cartesiano
permite então a consulta entre tabelas relacionadas utilizando uma condição de seleção apropriada. O resultado de um
produto cartesiano é uma nova tabela formada pela combinação das tuplas das tabelas sobre as quais se aplicou a
operação.
O formato geral do produto cartesiano entre duas tabelas R e S é: R X S
Suponhamos que uma consulta deseja encontrar todos os funcionários que desenvolvem projetos em Brasília. Para tanto,
utilizaremos a seguinte expressão:
Consulta
11
= EMPREGADO/PROJETO X PROJETO
A partir da expressão da Consulta
11
teremos os seguintes resultados:
Tabela 7.9a. Tabela com Resultados da Consulta
11
RG Empregado Número Projeto Nome Número Localização
20202020 5 Financeiro 1 5 São Paulo
20202020 5 Motor 3 10 Rio Claro
20202020 5 Prédio Central 20 Campinas
20202020 10 Financeiro 1 5 São Paulo
20202020 10 Motor 3 10 Rio Claro
20202020 10 Prédio Central 20 Campinas
30303030 5 Financeiro 1 5 São Paulo
30303030 5 Motor 3 10 Rio Claro
30303030 5 Prédio Central 20 Campinas
40404040 20 Financeiro 1 5 São Paulo
40404040 20 Motor 3 10 Rio Claro
40404040 20 Prédio Central 20 Brasília
50505050 20 Financeiro 1 5 São Paulo
50505050 20 Motor 3 10 Rio Claro
50505050 20 Prédio Central 20 Brasília
Em seguida, necessitamos selecionar as tuplas resultantes que estão devidamente relacionadas, que são as que possuem o
mesmo valor em número do projeto e número e cuja localização seja ‘Brasília. Para tanto, utilizaremos a seguinte expressão:
Consulta
12
= ¬
rg_empregado, número
(c
(número_projeto = número) .and. (localização = ‘Brasília’)
(CONSULTA11))
A partir da expressão da Consulta
12
, teremos os seguintes resultados:
Tabela 7.9b. Tabela com Resultados da Consulta
12
RG Número
40404040 20
50505050 20
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
89
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
2.6. Operação Junção
A operação junção atua de forma similar á operação produto cartesiano, porém, a tabela resultante conterá apenas
as combinações das tuplas que se relacionam de acordo com uma determinada condição de junção. A forma geral da
operação junção entre duas tabelas R e S é a seguinte:
R
<condição de junção>
S
Suponhamos que uma consulta deseja encontrar todos os funcionários que desenvolvem projetos em Brasília. Para tanto,
utilizaremos a seguinte expressão:
Consulta
13
= EMPREGADOS/PROJETOS
número_projeto = número
PROJETOS
A partir da expressão da consulta
13
teremos os seguintes resultados:
Tabela 7.10a. Tabela com Resultados da Consulta
13
RG_Empregado Número_Projeto Nome Número Localização
20202020 5 Financeiro 1 5 São Paulo
20202020 10 Motor 3 10 Rio Claro
30303030 5 Financeiro 1 5 São Paulo
40404040 20 Prédio Central 20 Brasília
50505050 20 Prédio Central 20 Brasília
Para finalizar o processo, necessitamos selecionar as tuplas onde a localização seja igual a Brasília.
Consulta
14
= c
localização = ‘Brasília’
(CONSULTA
13
)
A partir da expressão da consulta
14
teremos os seguintes resultados:
Tabela 7.10b. Tabela com Resultados da Consulta
14
RG_Empregado Número_Projeto Nome Número Localização
40404040 20 Prédio Central 20 Brasília
50505050 20 Prédio Central 20 Brasília
Conforme pode ser visto a partir da comparação dos resultados das Tabelas 7.9b e 7.10b, a operação de junção e o
produto cartesiano fornecem o mesmo resultado, porém a operação junção permite que o processamento seja mais simples.
3. Forma Normal de Boyce-Codd
A forma normal de Boyce-Codd (FNBC) foi proposta como uma forma mais simples que a 3ª FN, mas foi considerada mais
restrita na medida em que toda relação que está na FNBC também está na 3ª FN, entretanto, o inverso não é verdadeiro.
A definição formal da FNBC difere ligeiramente da definição da 3ª FN. Um esquema da relação R está na FNBC se,
sempre, uma dependência funcional não-trivial
1
X ¬ A se mantiver em R, X for uma superchave de R. A condição b
da 3ª FN está ausente. De forma esquemática, podemos representar a FNBC como (Figura 7.1):
Figura 7.1. – Representação esquemática da FNBC
Uma relação R está em BCNF se:
• Para todas as DF’s de R não triviais X ¬ Y.
X for superchave de R.
(Basta existir uma DF em que X não seja superchave, para R não estar em
BCNF. Se isso acontecer, diz-se que essa DF viola a condição de BCNF)
1 É o tipo de dependência que indica que um determinante identifica outro atributo qualquer.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
90
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Consideremos o seguinte exemplo:
Tabela 7.11. Representação da tabela Empregado
Empregado RG Nome CodDepartamento Nome_Depto RG_Ger_Depto
Como é possível perceber, na Tabela 7.11 temos as seguintes dependências funcionais:
a. RG ¬ {Nome_Depto, RG_Ger_Depto}
b. RG ¬ CodDepartamento
c. CodDepartamento ¬ {Nome_Depto, RG_Ger_Depto}
Analisando a Tabela 7.11, sob a ótica das regras da FNBC, é possível perceber que a tabela em análise não atende a
todos os requisitos que a regra define, pois a chave RG não é uma superchave da tabela Empregado.
Figura 7.2. Representação esquemática da regra para normalização FNBC
• A idéia é usar uma DF X ¬ Y que viole a condição de BCNF.
• Calcula-se X
+
.
– Não dá todos os atributos, caso contrário X seria superchave.
• Decompõe-se R em duas relações, R
1
e R
2
, com os seguintes esquemas:
1. R
1
¬ R
+
2. R
2
¬ X L (atrib(R) – (X
+
))
Para transformarmos a Tabela 7.11 na FNBC é necessário decompor a tabela em esquemas menores.
Tabela 7.12a. Representação da tabela Empregado
Empregado RG Nome
Tabela 7.12b. Representação da tabela Departamento
Departamento CodDepartamento Nome_Depto RG
Tabela 7.12c. Representação da tabela Gestores
Gerentes RG Nome CodDepartamento
Analisando as dependências funcionais das Tabelas 7.12a, 7.12b e 7.12c, temos:
a. RG ¬ {Nome}
b. RG ¬ {CodDepartamento, Nome_Depto}
c. RG ¬ {Nome, CodDepartamento}
Como pode ser visto nas apresentadas, como RG passou a ser uma superchave, podemos dizer que as relações agora
atendem aos pressupostos da FNBC.
Diz-se que uma decomposição de R em R
1
e R
2
é sem perda (Lossless join) quando, ao juntarmos as tuplas de R
1
com as
tuplas de R2 (igualando os atributos com o mesmo nome), obtivermos exatamente as tuplas de R.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
91
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
4. 4ª e 5ª Formas Normais
Além das formas funcionais descritas, existem outras que representam um refinamento das formas anteriores.
4.1. 4ª Forma Normal
Uma relação R está na quarta forma normal (4ªFN) se está na FNBC e para qualquer dependência multivalor não trivial
X ¬ Y, X é uma superchave.
4.2. 5ª Forma Normal
Uma relação R está na quinta forma normal (5ªFN) se está na 4ªFN e não tem nenhuma dependência de junção. Uma
dependência de junção é a situação onde uma relação R e certas projeções R
1
, . . . ,R
n
, diz-se que há uma dependência
de junção (de R em relação a R
1
, . . . ,R
n
) se R pode ser reconstituída como a junção de R
1
, . . . ,R
n
.
Apesar do refinamento que apresentam, as formas funcionais mais especializadas que a FNBC costumam ser raramente
utilizadas pois, além da dificuldade de aplicação, podem redundar em redução de performance. A Figura 7.3 mostra uma
representação esquemática das formas de normalização.
Figura 7.3. Representação esquemática do processo de normalização
5
a
FN
4
a
FN
Boyce-Codd
3
a
FN
2
a
FN
1
a
FN
1
a
FN – Todos atributos assumem valores
atômicos ou elementares.
2
a
FN – Estar na 1
a
FN e todos os
atributos que não participam da chave
são dependentes funcionalmente de toda a
chave e não de parte dela.
3
a
FN – Estar na 2
a
FN cada atributo não
chave depende diretamente da chave, não
havendo dependência transitiva.
FNBC – Estar na 3
a
FN e uma dependência
funcional não-trivial X ¬ A se mantiver
em R, X for uma Superchave de R.
4
a
FN – Estar na FNBC e não apresentar
dependência multivalor.
5
a
FN – Estar na 4
a
FN e não apresentar
dependência de junção.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
92
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Capítulo 8 – Metodologia para Projeto Prático de Banco de Dados
1. Aspectos Relevantes a serem Considerados
Atualmente, devem-se considerar alguns aspectos relevantes para atingir a eficiência e a eficácia dos sistemas
informatizados desenvolvidos, a fim de atender seus usuários nos mais variados domínios de aplicação.
Entre os mais relevantes, podemos destacar:
a. Os projetos Lógico e Funcional do Banco de Dados devem ser capazes de prever o volume de informações
armazenadas a curto, médio e longo prazo. Os projetos devem ter uma grande capacidade de adaptação
para os três casos mencionados.
b. Deve-se ter generalidade e alto grau de abstração de dados, possibilitando confiabilidade e eficiência no
seu armazenamento e permitindo a utilização de diferentes tipos de gerenciadores de dados por meio
de linguagens de consultas padronizadas.
c. Deve-se ter projeto com uma interface ágil e com uma “rampa ascendente” para propiciar aprendizado
suave ao usuário, no intuito de minimizar o esforço cognitivo;
d. Implementação de um projeto de interface compatível com múltiplas plataformas (UNIX, Windows NT,
Windows Workgroup).
e. Independência de Implementação da Interface em relação aos SGBDs que darão condições às operações
de armazenamento de informações (ORACLE, SYSBASE, INFORMIX, PADRÃO XBASE).
f. Conversão e mapeamento da diferença semântica entre os paradigmas utilizados no desenvolvimento
de interfaces (Imperativo (ou procedural), Orientado a Objeto, Orientado a evento), servidores de dados
(Relacional) e programação dos aplicativos (Imperativo, Orientado a Objetos).
2. Ambiente de Desenvolvimento de Aplicativos
A Figura 8.1 ilustra um ambiente genérico de desenvolvimento de aplicativos. Nessa Figura, a diferença (gap semântico)
entre os paradigmas utilizados para a construção de interfaces, o armazenamento de informações, e a programação dos
aplicativos são detalhados para ressaltar a importância de estruturas “Case” e “Cursores”. As estruturas “Case” são
utilizadas para converter as alterações e solicitações ocorridas na interface do aplicativo em uma linguagem que seja
capaz de ser processada pelos servidores de dados. A construção da linguagem é feita por intermédio da composição de
cadeias de caracteres, usualmente utilizando o padrão SQL empregado nos servidores de dados relacionais. Quando um
acesso ao SGBD é requerido, o programa estabelece uma conexão com o SGBD que está instalado no servidor.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
93
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Figura 8.1. Representação de um ambiente genérico de desenvolvimento de aplicativos
Fonte: Adaptado de Silberschatz (2006).
Uma vez que a conexão é criada, o programa cliente pode se comunicar com o SGBD. Um padrão chamado de Conectividade
Base de Dados Aberta (Open DataBase Connectivity – ODBC) provê uma Interface para Programação de Aplicações
(API), que permite que os programas no lado cliente possam chamar o SGBD, desde que as máquinas clientes, como
o servidor, tenham o necessário software instalado. Muitos vendedores de SGBDs disponibilizam drivers específicos
para seus sistemas. Dessa maneira, um programa cliente pode se conectar a diversos SGBDRs e enviar requisições de
consultas e transações usando API, que são processados nos servidores. Após o processamento de uma chamada de
função (levando uma cadeia de caracteres ou programas armazenados), o resultado é fornecido pelo servidor de dados
por meio de tabelas em memória. Os resultados das consultas são enviados para o programa cliente, que pode processá-lo
ou visualizá-lo conforme a necessidade. O conjunto resposta para uma consulta pode ser uma tabela com zero, uma ou
múltiplas tuplas, dependendo de quantas linhas foram encontradas com o critério de busca.
Quando uma consulta retorna múltiplas linhas, é necessário declarar um “CURSOR” para processá-las. Um cursor é similar
a uma variável de arquivo ou um ponteiro de arquivo, que aponta para uma única linha (tupla) do resultado da consulta. Em
SQL os cursores são controlados por três comandos: OPEN, FETCH, CLOSE. O cursor é iniciado com o comando OPEN,
que executa a consulta, devolve o conjunto resultante de linhas e coloca o cursor para a posição anterior à primeira linha
do resultado da consulta. O comando FETCH, quando executado pela primeira vez, devolve a primeira linha nas variáveis
do programa e coloca o cursor para apontar para aquela linha. Subsequentes execuções do comando FETCH avançam o
cursor para a próxima linha no conjunto resultante e retornam a linha nas variáveis do programa. Quando a última linha é
processada, o cursor é desbloqueado com o comando CLOSE. Os cursores existem principalmente para que linguagens de
programação que não permitem abstração para conjunto de registros, como C, possam receber as linhas da resposta de
uma consulta SQL uma de cada vez. Com a utilização de “CURSORES”, apresentam-se esses dados como resultados das
consulta, por meio de itens que representam os elementos de interface com o usuário, atendendo os preceitos impostos
pelos diferentes paradigmas possivelmente envolvidos. Com isso os resultados são mostrados utilizando o objeto padrão
da interface, disponíveis nas ferramentas de construção de interfaces. Dessa forma, o ciclo de busca de informação nos
mais variados servidores tem início e fim na interface com o usuário.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
94
Teoria e Metodologia do Projeto de Banco de Dados Unidade III
Figura 8.2. Arquitetura Cliente-Servidor
Fonte: Adaptado de Silberschatz (2006).
É de fundamental importância que se construam aplicativos cujos projetos de interface sejam “ortogonais” aos projetos
de implementação de acesso aos servidores de dados. Na implementação de sistemas de informação, deve-se utilizar uma
arquitetura de base de dados relacional que seja independente de um determinado repositório de dados (gerenciadores
Access, Oracle, Sybase, Informix).
A Figura 8.2 ilustra a utilização de conversores genéricos tanto para interfaces quanto para os servidores de dados. Esses
conversores são construídos para padronizar o controle de compartilhamento de dados, independente da ferramenta de
interface ou do servidor de dados.
Em situações práticas, esses conversores são denominados comumente de drivers.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
95
Capítulo 9 – Algoritmos para Processamento e Otimização de Consultas
1. Processamento de Consultas
Um dos principais componentes de todo sistema de gerência de bancos de dados é o processador de consultas que, ao
receber uma consulta Q, prepara um plano de execução para Q, consistindo de operações de mais baixo nível, implementadas
pelo subsistema de armazenamento.
Diferentes técnicas podem ser usadas para processar, otimizar e executar consultas de alto nível, como as consultas feitas
usando SQL. Uma consulta deve ser examinada (por meio de um scanner), analisada (por meio de um parser) e validada.
O scanner identifica os componentes da linguagem (tokens) no texto da consulta, enquanto o parser checa a sintaxe
da consulta para determinar se essa foi formulada seguindo as regras de sintaxe (regras de gramática) da linguagem. A
consulta também é validada por meio da checagem de que todos os nomes de atributos e tabelas são válidos e corretos
semanticamente. Uma representação interna da consulta é então criada, geralmente usando-se uma estrutura de árvores
ou grafos, chamada de árvore de consulta ou grafo de consulta.
O SGBD deve, então, determinar uma estratégia de execução para recuperação dos resultados da consulta, dos arquivos
internos do banco de dados. Uma consulta geralmente possui várias possíveis estratégias de execução, e o processo
para escolher entre elas, umas das melhores, é conhecido como otimização de consultas.
Duas abordagens são usadas no processamento de consultas: utilização de regras heurísticas e estimativa de custo.
Usualmente, estas duas abordagens são combinadas na otimização de uma consulta. Portanto, a otimização envolve:
• determinação de uma expressão equivalente mais eficiente; e
• seleção da “melhor” estratégia de processamento para a consulta (plano de acesso).
1.1. Etapas no Processamento de uma Consulta
1. Análise Sintática/Semântica (Scanner, Parser e Validação), que contém as etapas de verificação de
sintaxe, verificação dos identificadores (relações, atributos) e a verificação de autorização de acesso.
2. Tradução para uma estrutura de armazenamento bem definida (Árvore de Consulta).
3. Otimização da Consulta.
4. Escolha de um Plano de Acesso.
5. Geração de Código e Execução da Consulta.
Unidade IV
Armazenamento de Dados, Indexação,
Processamento de Consultas e
Projeto Físico
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
96
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
A Figura 9.1 apresenta um esquema reduzido contendo as etapas para o processamento de consultas de alto nível.
Figura 9.1. Representação esquemática das etapas de processamento de consultas
Consulta numa linguagem de alto nível
SCANNER, PARSER E VALIDAÇÃO
Forma intermediária da consulta
OTIMIZADOR DE CONSULTAS
Plano de acesso (ou plano de execução)
GERADOR DE CÓDIGO
Código para executar a consulta
PROCESSADOR DO BANCO DE DADOS

Resultado da consulta
2. Otimização de Consultas
A otimização de consultas consiste na escolha de estratégias eficientes para o processamento de consultas, visando minimizar:
• o número de acessos à memória secundária (disco);
• a quantidade de memória principal necessária.
Para o entendimento dessa definição, devemos ter em mente as seguintes informações.
• Quando expressamos uma consulta, apenas informamos o resultado que desejamos obter, mas não o melhor
caminho para obtê-lo. Logo, o SGBD deve se encarregar dessa tarefa.
• As consultas expressas em uma linguagem de alto nível (SQL, por exemplo) são transformadas pelos sistemas
(SGBD) para poderem ser processadas.
• O processamento da consulta é a busca de uma expressão equivalente, que torne mais rápida a execução
dessa consulta (redução no tamanho das tabelas intermediárias e menor custo de acesso).
• O tempo gasto no processo de otimização deve ser menor do que o tempo de acesso sem a otimização.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
97
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
Suponhamos que um banco de dados apresente as seguintes tabelas:
• Fornecedores: codf, nomef, cidade (100 tuplas)
• Peças: codp, nomep, cor, peso (200 tuplas)
• Embarques: codf, codp, qtde (10000 tuplas)
Suponhamos agora que se deseja executar uma consulta que busque o nome de todos os fornecedores que fornecem a peça
cujo código é “P2”. A expressão para executar a consulta pode ser:
SELECT nomef FROM fornecedores, embarques WHERE codf = codf and codp = “P2”;
Para efetuar a consulta podemos utilizar dois processos:
a. Processamento Normal:
• Produto Cartesiano de fornecedores e embarques (100 x 10000 = 1000000 tuplas)
• Seleção das tuplas desse produto que satisfazem a condição (50 tuplas, por exemplo, com 6 atributos)
• Projeção sobre o nomef (50 tuplas, com um atributo)
b. Estratégia para otimizar:
• Seleção das tuplas de embarques onde codp = “P2” (50 tuplas)
• Junção Natural desse resultado com a relação fornecedores (50 tuplas)
• Projeção sobre nomef (50 tuplas)
2.2. O Processo de Otimização
Existem duas técnicas básicas para otimização: as baseadas em heurísticas para a ordenação das operações de acesso
ao banco de dados que participarão da estratégia de acesso; e as que estimam sistematicamente o custo de estratégias
de execução diferentes e escolhem o plano de execução com o menor custo estimado.
2.2.1. Otimização Heurística
A representação de consultas por meio de uma estrutura bem definida permite a transformação da consulta em uma série
de expressões equivalentes. Nessa etapa, são feitas transformações de uma expressão que representa uma consulta em
outras equivalentes mediante o uso de regras. Uma série de transformações baseadas em heurísticas podem ser aplicadas
em uma consulta para melhorá-la com relação ao seu desempenho de execução.
2.3. Regras Gerais para Otimização
1. Executar operações de seleção o mais cedo possível.
2. Combinar seleções com um produto cartesiano de forma a produzir uma junção natural.
3. Aplicar operações de projeção de forma antecipada (transferir ou inserir projeções, sempre que
necessário). Os únicos atributos que devem permanecer num esquema são aqueles que aparecem no
resultado ou aqueles necessários para o processamento de consultas subseqüentes.
4. Aplicar operações em grupo à medida que se percorre as tuplas (evita a geração de muitas tabelas
intermediárias).
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
98
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
5. Procurar subexpressões comuns em uma árvore (computá-las uma única vez e guardá-las em uma tabela
temporária).
Ainda nas regras, as seguintes considerações são importantes:
• A combinação de operações evita repetitivas leituras às mesmas relações.
• Operações unárias (seleção e projeção) são mais econômicas que operações binárias, pois trabalham sobre uma
única relação. Sempre que possível, devem ser antecipadas.
As expressões na álgebra relacional possuem várias formas de se apresentarem, assim como as expressões matemáticas.
Deve-se valer das propriedades de associatividade e comutatividade a fim de simplificar ao máximo tais consultas.
2.3.1. Rotinas de Acesso para o Processamento de Consultas
Cada SGBD implementa um certo número de rotinas de acesso a bancos de dados, as quais são escritas para implementar
as operações relacionais, tais como Seleção ou Junção ou combinações destas operações. Uma estratégia de execução é
usualmente implementada por meio da chamada de uma ou mais dessas rotinas de acesso.
2.4. Otimização de Planos de Acesso
O processo de otimização de planos de acesso gera planos de operadores para as versões das consultas resultantes do
processo de transformações lógicas, estabelece os custos de cada plano gerado e escolhe o de menor custo para processar
a consulta. Esse processo é geralmente dividido em três etapas: geração de planos, avaliação de custos e escolha de planos.
2.4.1. Geração de Planos
Essa etapa mapeia a consulta resultante das transformações lógicas em seqüências de operações denominadas planos de
acesso. Na geração de planos, o otimizador deve planejar suas estratégias de acesso, utilizando da melhor forma possível
os caminhos de acesso já existentes e estimar custos de processamento em termos de tamanho das tabelas e acessos
ao disco. Um Plano de acesso para uma consulta inclui não somente as relações operacionais a serem executadas, mas
também os índices a serem utilizados e a ordem em que as tuplas devem ser acessadas, bem como a ordem de execução
das operações.
2.4.2. Estimativas de Custo de Acesso
Fatores que influenciam na estimativa de custos de acesso:
• proximidade física das tuplas;
• ordenação física das tuplas;
• presença de índices e o seu tipo (índice clustering ou não, hash etc.)
2.5. Otimização Baseada em Custos
As funções do custos são baseadas em estatísticas geradas pelo próprio SGBD. São apenas estimativas e, por não serem
exatas, correm o risco de gerar resultados dos quais a estratégia escolhida para otimização possa não ser a melhor. As
estatísticas são baseadas em informações armazenadas para utilização nessas funções, tais como o número de tuplas
da tabela, os índices secundários e suas chaves e a cardinalidade entre as tabelas.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
99
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
Capítulo 10 – Técnicas de Controle de Concorrência
Em nível lógico, o banco de dados é descrito por um esquema conceitual global consistindo em um conjunto de objetos
lógicos; em nível físico, é descrito por uma série de esquemas internos, um para cada nó onde está armazenado; cada
esquema interno consiste em um conjunto de objetos físicos.
Os mapeamentos do esquema conceitual global para os esquemas internos definem a forma de distribuição do banco e
a correspondência entre objetos físicos e objetos lógicos. Esses mapeamentos poderão determinar que certos conjuntos
de objetos físicos armazenem cópias dos mesmos dados. Os objetos lógicos são manipulados por meio de comandos da
LMD e os objetos físicos mediante ações elementares.
Uma transação de banco de dados é uma unidade de interação com um SGBD ou com um sistema similar de processamento
de transações, que deve ser integralmente completada ou abortada. Um sistema de banco de dados deve assegurar as
propriedades de Atomicidade, Consistência, Isolamento e Durabilidade (ACID) para cada transação. Na prática, essas
propriedades são frequentemente relaxadas de certa forma para aperfeiçoar a execução e melhorar o desempenho do
sistema. Em alguns sistemas, transações são também vistas como Unidades Lógicas de Trabalho (LUW - Logical Unit
of Work). Em SGBDs, a capacidade de manipular transações enseja ao usuário garantir a integridade do banco de dados
mantida.
Essa garantia só pode ser alcançada devido a um conjunto de operações que têm origem em um estudo ligado em quatro
regras fundamentais para gerenciamento de dados em ambientes multiusuário. Essas regras, as propriedades ACD, estão
relacionadas ao seguinte.
• Atomicidade: É a propriedade que garante que todas as transações sejam indursívas em sua execução ou
nenhuma delas será.
• Consistência: O banco de dados deve estar em um estado legal, quando a transação se inicia e quando for
executada. Uma operação não deve violar as regras ou restrições de integridade do banco, que deve continuar
consistente.
• Isolamento: Mesmo que várias transações ocorram paralelamente, elas devem parecer isoladas uma das
outras. Isso significa que nenhuma operação fora da transação pode ver o dado em um estado intermediário
e nenhuma operação deve influenciar as outras. Resultados parciais de uma transação não podem ser vistos
por outras transações concorrentes.
• Durabilidade: Segurança em que se uma transação é finalizada com sucesso, seus resultados serão
persistentes e não serão desfeitos, a não ser por outra transação, mesmo se houver falhas no sistema após
a sua finalização.
A execução de uma transação é controlada pelo gerente de transações (GT) do nó onde foi submetida. Em nível lógico,
a execução de uma transação consiste em todas as operações ali executadas entre o começo e o fim da transação. É
delimitada pelo.
• COMEÇO-DE-TRANSAÇÃO: o GT, ao interceptar este comando, cria uma área de trabalho para a transação;
comandos da LMD: consultas puras acessam objetos lógicos do banco de dados trazendo-os para a área
de trabalho, se já lá não estiverem. Atualizações sobre os objetos lógicos são mantidas na própria área de
trabalho, não se tornando visíveis de imediato a outras transações;
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
100
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
• FIM-DE-TRANSAÇÃO: invoca o protocolo bifásico para modificar todas as cópias de todos os objetos lógicos
afetados por atualizações executadas pela transação. Os valores dos objetos lógicos são obtidos da área de
trabalho.
Suponhamos que em cada nó participando do processamento da transação há uma área de trabalho da transação.
Todas as operações a nível lógico são sempre traduzidas em sequências de operações a nível físico. Mais precisamente,
uma execução de um grupo de transações gera, em cada nó, onde o banco está armazenado, uma sequência de ações
elementares, que presumimos de dois tipos:
• R(X) ação de leitura que recupera os valores dos objetos físicos, cujo nome está no conjunto X para a área de
trabalho local da transação que gerou a ação;
• W(X) ação de atualização que escreve os novos valores dos objetos físicos em X no banco de dados local.
Assim, a execução de um comando da LMD (que é uma operação em nível lógico) poderá gerar várias ações do tipo R(X)
para recuperar objetos físicos que ainda não estão na área de trabalho da transação. Porém, um comando da LMD nunca
gerará ações elementares do tipo W(X) pois o banco de dados não é alterado de imediato. Apenas quando o protocolo
bifásico atingir a segunda fase, ações elementares do tipo W(X) serão geradas para efetivar alterações nos bancos de
dados locais.
Há duas suposições importantes para controle de concorrência a se ressaltar aqui:
1. Controle de concorrência será feito em nível dos objetos físicos. Portanto, um mecanismo de controle de
concorrência deverá disciplinar a intercalação das ações elementares de diferentes transações em cada nó.
2. A semântica das transações não será levada em conta pelos mecanismos de controle de concorrência.
Como consequência, o controle de concorrência deverá depender apenas das sequências de operações de leitura/atualização
sobre os objetos físicos armazenados nos vários bancos de dados locais, ou seja, das sequências de operações R(X)
e W(X) executadas contra os bancos de dados locais. Uma execução concorrente E de um conjunto T de transações
pode, então, ser abstraída por um conjunto L= { L1 ,..., Ln }, onde Li é a sequência de ações elementares R(X) ou W(X)
executadas contra o banco de dados do nó i que foram geradas em E. O conjunto L é chamado de um escalonamento
global para T e a sequência Li é chamada do escalonamento local ao nó i para T. Usaremos Ri(X) ou Wi(X) para indicar
ações elementares R(X) ou W(X) executadas a favor da transação Ti em um escalonamento local.
Frequentemente escreveremos Ri (x1,..., xk ) em lugar de Ri ( { x1 ,..., xk } ), e semelhantemente para ações de atualização.
Como exemplos desses conceitos, considere um banco de dados distribuído armazenado em dois nós. Os esquemas
internos são modelados por dois conjuntos de objetos físicos, D1 = { x1 ,y1 } e D2 = { x2 }, onde x1 e x2 armazenam
cópias dos mesmos dados.
Um escalonamento global para duas transações T1 e T2 nesse contexto poderia ser L = { L1 , L2 }, onde L1 = R1(y1)
R2(x1) W2(x1) W1(x1) e L2 = R1(x2) W1(x2) W2(x2)
Ou seja, L1 representa a seguinte sequência de ações elementares executadas no primeiro nó:
• T1 lê o objeto físico y1
• T2 lê o objeto físico x1
• T2 escreve no objeto físico x1
• T1 escreve no objeto físico x1
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
101
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
Para o segundo nó, L2 representa a seguinte sequência:
• T1 lê o objeto físico x2
• T1 escreve no objeto físico x2
• T1 escreve no objeto físico x1
Tanto a teoria de correção quanto o estudo do comportamento dos métodos de controle de concorrência serão baseados
em propriedades de escalonamentos globais.
2. Isolamento da Transação
O padrão SQL define quatro níveis de isolamento de transação em termos de três fenômenos que devem ser evitados
entre transações simultâneas.
• Dirty read
1
(leitura suja): situação onde uma transação lê dados escritos por uma transação simultânea não
efetivada (uncommitted).
• Nonrepeatable read
2
(leitura que não pode ser repetida): situação onde uma transação lê novamente dados
lidos anteriormente, e descobre que os dados foram alterados por outra transação (que os efetivou após ter
sido feita a leitura anterior).
• Phantom read
3
(leitura fantasma): situação onde uma transação executa uma segunda vez uma consulta
que retorna um conjunto de linhas que satisfazem uma determinada condição de procura, e descobre que
o conjunto de linhas que satisfazem a condição é diferente por causa de uma outra transação efetivada
recentemente.
Os quatro níveis de isolamento de transação, e seus comportamentos correspondentes, estão descritos na Tabela 10.1.
Tabela 10.1. Níveis de Isolamento da Transação SQL
Nível de isolamento Dirty Read Nonrepeatable Read Phantom Read
Read uncommitted Possível Possível Possível
Read committed Impossível Possível Possível
Repeatable read Impossível Impossível Possível
Serializable Impossível Impossível Impossível
2.1. Nível de isolamento Read Committed
Quando uma transação processada sob o nível de isolamento Read Committed (lê efetivado), o comando SELECT enxerga
apenas os dados efetivados antes da consulta começar; nunca enxerga dados não efetivados, ou as alterações efetivadas
pelas transações simultâneas durante a execução da consulta. Entretanto, o SELECT enxerga os efeitos das atualizações
anteriores executadas dentro da sua própria transação, mesmo que ainda não tenham sido efetivadas. Na verdade, o
1 Dirty read — A transação SQL T1 altera uma linha. Em seguida, a transação SQL T2 lê essa linha antes de T1 executar o comando COMMIT. Se depois T1 executar o comando
ROLLBACK, T2 terá lido uma linha que nunca foi efetivada e que, portanto, pode ser considerada como nunca tendo existido. (ISO-ANSI Working Draft) Foundation (SQL/
Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)
2 Nonrepeatable read — A transação SQL T1 lê uma linha. Em seguida a transação SQL T2 altera ou exclui essa linha e executa o comando COMMIT. Se T1 tentar ler essa linha
novamente, pode receber o valor alterado ou descobrir que a linha foi excluída. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32,
25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)
3 Phantom read — A transação SQL T1 lê um conjunto de linhas N que satisfazem a uma condição de procura. Em seguida, a transação SQL T2 executa comandos SQL que geram
uma ou mais linhas que satisfazem a condição de procura usada pela transação T1. Se depois a transação SQL T1 repetir a leitura inicial com a mesma condição de procura, será
obtida uma coleção diferente de linhas. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N.
do T.)
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
102
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
comando SELECT enxerga um instantâneo do banco de dados, como esse era no instante em que a consulta começou a
executar. Deve ser observado que dois comandos SELECT sucessivos podem enxergar dados diferentes, mesmo estando
dentro da mesma transação, se outras transações efetivarem alterações durante a execução do primeiro comando SELECT.
Os comandos UPDATE, DELETE e SELECT FOR UPDATE se comportam do mesmo modo que o SELECT para encontrar
as linhas de destino: somente encontram linhas de destino efetivadas até o momento do início do comando. Entretanto,
no momento em que foi encontrada, alguma linha de destino pode ter sido atualizada (ou excluída ou marcada para
atualização) por outra transação simultânea. Nesse caso, a transação que pretende atualizar fica aguardando a transação
de atualização que começou primeiro: efetivar ou desfazer. Se a transação de atualização que começou primeiro desfizer
as atualizações, então seus efeitos são negados e a segunda transação de atualização pode prosseguir com a atualização
da linha original encontrada. Se a transação de atualização que começou primeiro efetivar as atualizações, a segunda
transação de atualização ignora a linha caso tenha sido excluída pela primeira transação de atualização, senão tenta
aplicar sua operação na versão atualizada da linha. A condição de procura do comando (a cláusula WHERE) é avaliada
novamente para verificar se a versão atualizada da linha ainda corresponde à condição de procura. Se corresponder, a
segunda transação de atualização prossegue sua operação começando a partir da versão atualizada da linha.
Devido à regra acima, é possível um comando de atualização enxergar um instantâneo inconsistente: pode enxergar os
efeitos dos comandos simultâneos de atualização que afetam as mesmas linhas que está tentando atualizar, mas não
enxerga os efeitos desses comandos de atualização nas outras linhas do banco de dados. Esse comportamento torna o
Read Committed inadequado para os comandos envolvendo condições de procura complexas. Entretanto, é apropriado
para casos mais simples.
Exemplificando, consideremos a atualização do saldo bancário pela transação mostrada Figura 10.1.
Figura 10.1. Exemplo de Atualização de Saldo Bancário
BEGIN;
UPDATE conta SET saldo = saldo + 100.00 WHERE num_conta = 12345;
UPDATE conta SET saldo = saldo - 100.00 WHERE num_conta = 7534;
COMMIT;
Se duas transações desse tipo tentam mudar simultaneamente o saldo da conta 12345, é claro que se deseja que a
segunda transação comece a partir da versão atualizada da linha da conta. Uma vez que cada comando afeta apenas
uma linha predeterminada, permitir enxergar a versão atualizada da linha não cria nenhum problema de inconsistência.
Como no modo Read Committed, cada novo comando começa com um novo instantâneo incluindo todas as transações
efetivadas até esse instante; de qualquer modo, os próximos comandos na mesma transação vão enxergar os efeitos
das transações simultâneas efetivadas. O ponto em questão é se, dentro de um único comando, é enxergada uma visão
totalmente consistente do banco de dados.
O isolamento parcial da transação fornecido pelo modo Read Committed é adequado para muitas aplicações, e esse
modo é rápido e fácil de ser utilizado. Entretanto, para aplicações que efetuam consultas e atualizações complexas,
pode ser necessário garantir uma visão do banco de dados com consistência mais rigorosa que a fornecida pelo modo
Read Committed.
2.2. Nível de Isolamento Serializável
O nível Serializável fornece o isolamento de transação mais rigoroso. Esse nível emula a execução serial das transações,
como se todas as transações fossem executadas uma após a outra, em série, em vez de simultaneamente. Entretanto, as
aplicações que utilizam esse nível de isolamento devem estar preparadas para tentar executar novamente as transações,
devido a falhas de serialização.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
103
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
Quando uma transação está no nível serializável, o comando SELECT enxerga apenas os dados efetivados antes da
transação começar; nunca enxerga dados não efetivados ou alterações efetivadas durante a execução da transação
por transações simultâneas. Entretanto, o comando SELECT enxerga os efeitos das atualizações anteriores executadas
dentro da sua própria transação, mesmo que ainda não tenham sido efetivadas. É diferente do Read Committed, porque
o comando SELECT enxerga um instantâneo do momento de início da transação, e não do momento de início do comando
corrente dentro da transação. Portanto, comandos SELECT sucessivos dentro de uma mesma transação sempre enxergam
os mesmos dados.
Os comandos UPDATE, DELETE e SELECT FOR UPDATE se comportam do mesmo modo que o comando SELECT para
encontrar as linhas de destino: somente encontram linhas de destino efetivadas até o momento do início da transação.
Entretanto, alguma linha de destino pode ter sido atualizada (ou excluída ou marcada para atualização) por outra transação
simultânea no momento em que foi encontrada. Nesse caso, a transação serializável aguarda a transação de atualização
que começou primeiro efetivar ou desfazer as alterações. Se a transação que começou primeiro desfizer as alterações,
então seus efeitos são negados e a transação serializável pode prosseguir com a atualização da linha original encontrada.
Porém, se a transação que começou primeiro efetivar (e realmente atualizar ou excluir a linha, e não apenas selecionar
para atualização), então a transação serializável é cancelada e é apresentada uma mensagem de erro, pois uma transação
serializável não pode alterar linhas alteradas por outra transação após a transação serializável ter começado.
Quando a aplicação receber essa mensagem de erro deverá interromper a transação corrente e tentar executar novamente
toda a transação a partir do início. Da segunda vez em diante, a transação passa a enxergar a alteração efetivada
anteriormente como parte da sua visão inicial do banco de dados e, portanto, não existirá conflito lógico em usar a nova
versão da linha como ponto de partida para atualização na nova transação.
Deve ser observado que somente as transações que fazem atualizações podem precisar de novas tentativas; as transações
somente para leitura nunca estão sujeitas a conflito de serialização.
O modo serializável fornece uma garantia rigorosa que cada transação enxerga apenas visões totalmente consistentes do
banco de dados. Entretanto, a aplicação deve estar preparada para executar novamente a transação quando atualizações
simultâneas tornarem impossível sustentar a ilusão de uma execução serial. Como o custo de refazer transações complexas
pode ser significativo, esse modo é recomendado somente quando as transações, efetuando atualizações, contenham
lógica suficientemente complexa a ponto de produzir respostas erradas no modo Read Committed. Habitualmente, o
modo serializável é necessário quando a transação executa vários comandos sucessivos que necessitam enxergar visões
idênticas do banco de dados.
3. Bloqueio Explícito
Diversos SGBDs, baseados na linguagem SQL, fornecem vários modos de bloqueio para controlar o acesso simultâneo
aos dados nas tabelas. A maioria dos comandos SQL obtém, automaticamente, bloqueios nos modos apropriados para
garantir que as tabelas referenciadas não serão excluídas ou alteradas de forma incompatível enquanto o comando
estiver executando. Por exemplo, o comando ALTER TABLE não pode executar simultaneamente com outras operações
na mesma tabela.
3.1. Bloqueios no Nível de Tabela
Os nomes dos modos de bloqueio são históricos pois, de alguma forma, os nomes refletem a utilização típica de cada
modo de bloqueio — mas as semânticas são todas as mesmas. A única diferença real entre um modo de bloqueio e
outro é o conjunto de modos de bloqueio que cada um conflita. Duas transações não podem obter bloqueios com modos
conflitantes na mesma tabela ao mesmo tempo (Entretanto, uma transação nunca conflita consigo mesma. Por exemplo,
pode obter o bloqueio ACCESS EXCLUSIVE e posteriormente obter o bloqueio ACCESS SHARE na mesma tabela). Podem
ser obtidos simultaneamente modos de bloqueio não conflitantes por muitas transações. Em particular, deve ser observado
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
104
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
que alguns modos de bloqueio são autoconflitantes. Por exemplo, o modo de bloqueio ACCESS EXCLUSIVE não pode ser
obtido por mais de uma transação ao mesmo tempo, enquanto outros não são autoconflitantes. Por exemplo, o modo de
bloqueio ACCESS SHARE pode ser obtido por várias transações ao mesmo tempo. Uma vez obtido, o modo de bloqueio
permanece até o fim da transação.
3.1.1. Modos de Bloqueio no Nível de Tabela
A seguir, apresentamos alguns modos de bloqueio em nível de tabela.
• ACCESS SHARE: Conflita apenas com o modo de bloqueio ACCESS EXCLUSIVE. O comando SELECT e o
comando ANALYZE obtêm um bloqueio nesse modo nas tabelas referenciadas. Em geral, qualquer comando
que apenas lê a tabela sem modificá-la obtém esse modo de bloqueio.
• ROW SHARE: Conflita com os modos de bloqueio EXCLUSIVE e ACCESS EXCLUSIVE. O comando SELECT
FOR UPDATE obtém o bloqueio nesse modo na(s) tabela(s) de destino (além do bloqueio no modo ACCESS
SHARE para as demais tabelas referenciadas mas não selecionadas FOR UPDATE).
• ROW EXCLUSIVE: Conflita com os modos de bloqueio SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e
ACCESS EXCLUSIVE. Os comandos UPDATE, DELETE e INSERT obtêm esse modo de bloqueio na tabela de
destino (além do modo de bloqueio ACCESS SHARE nas outras tabelas referenciadas). Em geral, este modo
de bloqueio é obtido por todos os comandos que alteram os dados da tabela.
• SHARE UPDATE EXCLUSIVE: Conflita com os modos de bloqueio SHARE UPDATE EXCLUSIVE, SHARE,
SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE. Este modo protege a tabela contra alterações
simultâneas no esquema e a execução do comando VACUUM. Obtida pelo comando VACUUM (sem a opção
FULL).
• SHARE: Conflita com os modos de bloqueio ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW
EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE. Esse modo protege a tabela contra alterações simultâneas
nos dados. Obtido pelo comando CREATE INDEX.
• SHARE ROW EXCLUSIVE: Conflita com os modos de bloqueio ROW EXCLUSIVE, SHARE UPDATE
EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE. Esse modo de bloqueio
não é obtido automaticamente por nenhum comando do PostgreSQL.
• EXCLUSIVE: Conflita com os modos de bloqueio ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,
SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE. Esse modo permite apenas bloqueios
ACCESS SHARE simultâneos, ou seja, somente leituras da tabela podem prosseguir em paralelo com uma
transação que obteve esse modo de bloqueio. Esse modo de bloqueio não é obtido automaticamente por
nenhum comando do PostgreSQL.
• ACCESS EXCLUSIVE: Conflita com todos os modos de bloqueio (ACCESS SHARE, ROW SHARE, ROW
EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS
EXCLUSIVE). Esse modo garante que a transação que o obteve é a única acessando a tabela de qualquer
forma. Obtido pelos comandos ALTER TABLE, DROP TABLE, REINDEX, CLUSTER e VACUUM FULL. Esse é,
também, o modo de bloqueio padrão para o comando LOCK TABLE sem a especificação explícita do modo.
Dica 1: Somente o bloqueio ACCESS EXCLUSIVE bloqueia o comando SELECT (sem a cláusula FOR UPDATE).
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
105
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
3.2. Bloqueios no Nível de Linha
Além dos bloqueios em nível de tabela, existem os bloqueios no nível de linha. O bloqueio em nível de linha é obtido
automaticamente para uma linha específica quando a linha é atualizada (ou excluída ou marcada para atualização). O
bloqueio é mantido até a transação efetivar ou desfazer as alterações. Os bloqueios em nível de linha não afetam a
consulta aos dados; bloqueiam apenas escritas na mesma linha. Para obter um bloqueio em nível de linha sem, na verdade,
modificá-la, a linha deve ser selecionada por meio do comando SELECT FOR UPDATE. Deve ser observado que, após ser
obtido um bloqueio em nível de linha, a transação pode atualizar essa linha várias vezes sem medo de conflito.
De forma geral, os SGDs baseados em SQL não guardam em memória qualquer informação sobre as linhas alteradas,
portanto não existe limite de número de linhas bloqueadas de cada vez. Entretanto, o bloqueio de uma linha pode causar
escrita no disco; por exemplo, o comando SELECT FOR UPDATE altera as linhas selecionadas para marcá-las, ocasionando
escrita em disco.
Além dos bloqueios de tabela e de linha, também são utilizados bloqueios compartilhados e exclusivos no nível de página,
para controlar o acesso de leitura e escrita nas páginas da tabela no shared buffer pool. Esses bloqueios são liberados
imediatamente após a linha ser lida ou atualizada.
Normalmente os desenvolvedores de aplicação não precisam se preocupar com bloqueios em nível de página, sendo
mencionados somente para o assunto ficar completo.
3.3. Impasses
A utilização de bloqueios explícitos pode aumentar a probabilidade de acontecerem impasses (deadlocks), onde duas (ou
mais) transações mantêm bloqueios que a outra deseja. Por exemplo, se a transação 1 obtiver um bloqueio exclusivo
na tabela A e, depois, tentar obter um bloqueio exclusivo na tabela B, enquanto a transação 2 já possui um bloqueio
exclusivo na tabela B, e agora deseja obter um bloqueio exclusivo na tabela A, então nenhuma das duas transações
pode prosseguir. Nesse tipo de situação, é necessário que o SGBD detecte as situações de impasse, resolvendo-as,
interrompendo uma das transações envolvidas, permitindo que a(s) outra(s) prossiga(m). O ponto sensível desse tipo de
solução é saber exatamente qual transação será interrompida; é difícil prever, não se devendo confiar na previsão de
tratamento automático.
Deve ser observado que os impasses também podem ocorrer como resultado de um bloqueio no nível de linha, podendo
ocorrer mesmo que não se use bloqueios explícitos. Considere o caso onde existam duas transações simultâneas alterando
uma tabela. A primeira transação executa a instrução apresentada na Figura 10.2.
Figura 10.2. Exemplo de Atualização de Saldo Bancário (atualização I)
UPDATE conta SET saldo = saldo + 100.00 WHERE num_conta = 11111;
Esse comando obtém um bloqueio no nível de linha na linha com o número da conta especificado. Depois, a segunda
transação executa (Figura 10.3):
Figura 10.3. Exemplo de Atualização de Saldo Bancário (atualização II)
UPDATE conta SET saldo = saldo + 100.00 WHERE num_conta = 22222;
UPDATE conta SET saldo = saldo – 100.00 WHERE num_conta = 11111;
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
106
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
O primeiro comando UPDATE é bem-sucedido ao obter o bloqueio no nível de linha na linha especificada e, prossegue,
atualizando a linha. Entretanto, o segundo comando UPDATE descobre que a linha a ser atualizada está bloqueada e, fica
aguardando a transação que obteve o bloqueio terminar. A transação 2, agora, está aguardando a transação 1 completar
para poder continuar. Agora, a transação 1 executa (Figura 10.4):
Figura 10.4. Exemplo de Atualização de Saldo Bancário (atualização III)
UPDATE conta SET saldo = saldo - 100.00 WHERE num_conta = 22222;
A transação 1 tenta obter um bloqueio no nível de linha na linha especificada, mas não pode: a transação 2 já possui esse
bloqueio. Portanto, fica aguardando a transação 2 terminar. Assim sendo, a transação 1 está bloqueada pela transação
2, e a transação 2 está bloqueada pela transação 1: uma condição de impasse. Nesse caso, é necessário que o SGBD
detecte essa situação e interrompa uma das transações.
Geralmente a melhor defesa contra os impasses é evitá-los, tendo certeza de que todas as aplicações que utilizam o banco
de dados obtêm bloqueios em vários objetos em uma ordem consistente. No exemplo anterior, se as duas transações
tivessem atualizado as linhas na mesma ordem, não teria ocorrido nenhum impasse. Deve-se garantir, também, que o
primeiro bloqueio obtido em um objeto em uma transação seja aquele com o modo mais alto que será necessário para
esse objeto. Se for impraticável verificar essa situação antecipadamente, então os impasses podem ser tratados em
tempo de execução tentando executar novamente as transações interrompidas pelos impasses.
Enquanto a situação de impasse não for detectada, uma transação em busca de um bloqueio no nível de tabela ou no nível
de linha ficará aguardando indefinidamente pela liberação dos bloqueios conflitantes. Isso significa que é uma péssima
idéia as aplicações manterem transações abertas por longos períodos de tempo (por exemplo, aguardando a entrada de
dados pelo usuário).
4. Verificação da Consistência dos Dados no Nível da Aplicação
De certa forma, podemos dizer que cada transação enxerga um instantâneo do conteúdo do banco de dados, e as
transações, executando simultaneamente, podem, perfeitamente bem, enxergar instantâneos diferentes. Portanto, o
próprio conceito de “agora”, de alguma forma é mal definido. Normalmente isso não é um grande problema quando as
aplicações cliente estão isoladas umas das outras, mas se os clientes podem se comunicar por meio de canais externos
ao banco de dados, então podem acontecer sérias confusões.
Para garantir a validade corrente de uma linha e protegê-la contra atualizações simultâneas, deve ser utilizado o comando
SELECT FOR UPDATE ou uma declaração LOCK TABLE apropriada. O comando SELECT FOR UPDATE bloqueia apenas
as linhas retornadas contra atualizações simultâneas, enquanto o LOCK TABLE bloqueia toda a tabela.
As verificações de validade globais requerem considerações extras. Por exemplo, uma aplicação bancária pode desejar
verificar se a soma de todos os créditos em uma tabela é igual à soma de todos os débitos em outra tabela, num momento
em que as duas tabelas estão sendo ativamente atualizadas. Comparar os resultados de dois comandos SELECT SUM(...)
sucessivos não funciona confiavelmente no modo Read Committed, porque o segundo comando, provavelmente, vai
incluir resultados de transações não contados pelo primeiro comando. Realizar as duas somas em uma mesma transação
serializável fornece uma imagem precisa dos efeitos das transações efetivadas antes do início da transação serializável
— mas pode ser legitimamente questionado se a resposta ainda era relevante na hora em que foi entregue.
Se a própria transação serializável introduziu algumas alterações antes de tentar efetuar a verificação de consistência,
o valor prático da verificação se torna ainda mais discutível, porque agora são incluídas algumas, mas não todas as
alterações ocorridas após o início da transação. Em casos como esse, uma pessoa cuidadosa pode desejar bloquear
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
107
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
todas as tabelas necessárias para a verificação, para obter uma imagem da situação atual acima de qualquer suspeita.
Um bloqueio no modo SHARE (ou superior) garante não haver alterações não efetivadas na tabela bloqueada, fora as
alterações efetuadas pela própria transação corrente.
Deve ser observado, também, que quando se depende de bloqueios explícitos para evitar alterações simultâneas, deve ser
utilizado o modo Read Committed ou, no modo serializável, tomar o cuidado de obter os bloqueios antes de executar os
comandos. Um bloqueio obtido por uma transação serializável garante que nenhuma outra transação alterando a tabela
está executando, mas se o instantâneo enxergado pela transação for anterior à obtenção do bloqueio, pode ser que seja
anterior a algumas alterações na tabela que agora estão efetivadas.
O instantâneo de uma transação serializável é, na verdade, tirado no início da sua primeira consulta ou comando de
alteração de dados (SELECT, INSERT, UPDATE ou DELETE) sendo, portanto, possível obter bloqueios explicitamente
antes do instantâneo ser tirado.
5. Bloqueio e Índices
Os vários tipos de índice são tratados como mostrado a seguir.
• Índices B-tree: São utilizados bloqueios no nível de página, compartilhados ou exclusivos, de curta duração,
para acesso de leitura/escrita. Os bloqueios são liberados imediatamente após cada linha do índice ser lida ou
inserida. Os índices B-tree fornecem a mais alta simultaneidade, sem condições de impasse.
• Índices GiST e R-tree: São utilizados bloqueios no nível de índice, compartilhados ou exclusivos, para acesso
de leitura/escrita. Os bloqueios são liberados após o comando terminar.
• Índices Hash: São utilizados bloqueios no nível de página compartilhados e exclusivos para acessos de
leitura/escrita. Os bloqueios são liberados após a página ser processada. Os bloqueios no nível de página
fornecem uma simultaneidade melhor que os bloqueios no nível de índice, mas podem ocorrer impasses.
Em resumo, o índice B-tree oferece o melhor desempenho para aplicações simultâneas; uma vez que também possui mais
funcionalidades do que o índice hash, é o tipo de índice recomendado para aplicações simultâneas que necessitam indexar
dados escalares. Para tratar dados não escalares, os índices B-tree obviamente não podem ser utilizados; nessa situação,
os que desenvolvem a aplicação devem estar cientes do desempenho relativamente pobre dos índices GiST e R-tree.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
108
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
Capítulo 11 – Técnicas de Recuperação de Dados
1. Introdução
Existem algumas tarefas de manutenção que precisam ser realizadas regularmente para manter um servidor funcionando
sem problemas. É responsabilidade do administrador do banco de dados instalar os scripts apropriados, e verificar se a
execução está sendo bem-sucedida.
Uma tarefa de manutenção óbvia é a geração das cópias de segurança dos dados em períodos regulares. Sem uma cópia
de segurança recente, não há como fazer a recuperação após um desastre (falha de disco, incêndio, remoção por engano
de uma tabela crítica).
Outra tarefa de manutenção importante é a limpeza periódica do banco de dados, além do gerenciamento do arquivo de
registro (log).
2. Rotina de Limpeza
Cada SGBD possui um conjunto de comandos para efetuar rotinas de limpeza. No PostgreSQL o comando VACUUM é
utilizado para essa função e necessita ser executado regularmente para:
• recuperar o espaço em disco ocupado pelas linhas atualizadas e removidas.
• atualizar as estatísticas dos dados utilizadas pelo planejador de comandos do PostgreSQL.
• proteger contra perda de dados muito antigos devido ao recomeço do ID de transação.
A frequência e a abrangência das operações de VACUUM, realizadas devido aos motivos acima, variam dependendo
das necessidades da instalação. Portanto, os administradores de banco de dados devem compreender essas questões e
desenvolver uma estratégia de manutenção apropriada.
2.1. Recuperação do Espaço em Disco
De forma geral, um comando UPDATE ou DELETE em uma linha não remove imediatamente a versão antiga da linha. Essa
abordagem é necessária para obter os benefícios do controle de simultaneidade multiversão. A versão da linha não pode
ser removida enquanto houver possibilidade de ser acessada por outras transações. Mas no final, uma versão de linha
desatualizada ou excluída não terá mais interesse para nenhuma transação. O espaço ocupado deve ser recuperado para
ser reutilizado pelas novas linhas, evitando um crescimento sem fim da necessidade de espaço em disco.
Obviamente, uma tabela que recebe atualizações ou exclusões frequentes necessita ser limpa com mais frequência que
uma tabela que é atualizada raramente.
A forma padrão encontra as versões antigas das linhas e torna seus espaços disponíveis para ser utilizado novamente
dentro da tabela, mas não faz muito esforço para diminuir o tamanho do arquivo da tabela e devolver o espaço em disco
para o sistema operacional.
No PostgreSQL, se for necessário devolver espaço em disco para o sistema operacional pode ser utilizado o comando
VACUUM FULL — mas qual é a vantagem de liberar espaço em disco que deverá ser alocado novamente em breve?
Execuções do comando VACUUM padrão com frequência moderada é uma abordagem melhor do que a execução do
comando VACUUM FULL com baixa frequência, para manutenção de tabelas muito atualizadas.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
109
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
A prática recomendada para a maioria das instalações é agendar o comando VACUUM para todo o banco de dados uma
vez por dia, em horário de pouca utilização, suplementado por limpezas mais frequentes das tabelas muito atualizadas se
for necessário (Havendo vários bancos de dados em um agrupamento, não deve ser esquecido de limpar cada um deles;
o programa vacuumdb pode ser útil). Deve ser utilizado o VACUUM simples, e não o VACUUM FULL, para recuperação
rotineira de espaço.
O comando VACUUM FULL é recomendado para os casos onde se sabe que foi excluída a maior parte das linhas da
tabela e, portanto, o tamanho estável da tabela pode ser reduzido substancialmente pela abordagem mais agressiva do
comando VACUUM FULL.
Havendo uma tabela cujo conteúdo é excluído periodicamente, deve ser considerada a execução do comando TRUNCATE
em vez de utilizar DELETE seguido por VACUUM.
2.2. Atualização das Estatísticas do Planejador
O planejador de comandos depende das informações estatísticas sobre o conteúdo das tabelas para poder gerar bons
planos para os comandos. Essas estatísticas são coletadas pelo comando ANALYZE, que pode ser chamado por si próprio
ou como um passo opcional do comando VACUUM. É importante que as estatísticas estejam razoavelmente precisas,
senão o desempenho do banco de dados poderá ser degradado por planos mal escolhidos.
Assim como a execução do comando VACUUM para recuperar espaço, atualizações frequentes das estatísticas são mais
úteis para tabelas muito atualizadas que para tabelas raramente atualizadas, mas mesmo nas tabelas muito atualizadas
pode não haver necessidade de atualizar as estatísticas, se a distribuição dos dados não mudar muito. Uma regra empírica
simples é pensar sobre quanto os valores mínimos e máximos das colunas da tabela mudam. Por exemplo, uma coluna
timestamp contendo a data e hora da atualização da linha terá um valor máximo aumentando constantemente na medida
em que forem atualizadas ou adicionadas linhas à tabela; esse tipo de coluna, provavelmente, precisa de atualizações
mais frequentes das estatísticas do que, digamos, uma coluna contendo URLs de páginas acessadas em sítios da Web. A
coluna URL pode ser modificada com a mesma frequência, mas a distribuição estatística de seus valores provavelmente
muda de forma relativamente lenta.
É possível executar o comando ANALYZE em tabelas específicas, e mesmo em colunas específicas da tabela. Portanto,
existe flexibilidade para atualizar algumas estatísticas com mais frequência que outras se for requerido pela aplicação.
Entretanto, na prática, a utilidade dessa funcionalidade é duvidosa.
A prática recomendada, para a maioria das instalações, é agendar a execução do comando ANALYZE para todo o banco
de dados uma vez por dia, em horário de pouca utilização; é útil sua combinação com a execução do comando VACUUM
todas as noites. Entretanto, nas instalações onde as estatísticas das tabelas mudam de forma relativamente lenta,
pode-se considerar que essa frequência seja demasiada, e que a execução do comando ANALYZE com uma frequência
mais baixa seja suficiente.
Dica 1: Embora possa não ser muito produtivo aumentar a frequência de execução do comando ANALYZE
por coluna, pode valer a pena fazer ajustes por coluna do nível de detalhe das estatísticas coletadas pelo
comando ANALYZE. Colunas que são muito utilizadas em cláusula WHERE, e que contêm uma distribuição
de dados muito irregular, podem requerer um histograma dos dados com granulação mais fina que as demais.
Veja o comando ALTER TABLE SET STATISTICS.
3. Rotina de Reindexação
Em algumas situações vale a pena reconstruir índices periodicamente, utilizando o comando REINDEX. Existe, também,
a aplicação contrib/reindexdb que pode reindexar todo o banco de dados.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
110
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
4. Manutenção do Arquivo de Registro
É uma boa ideia salvar a saída do registro (log) do servidor de banco de dados em algum lugar, em vez de simplesmente
direcionar para /dev/null. A saída do registro é valiosa para fazer diagnóstico de problemas. Entretanto, a saída do registro
tende a se tornar volumosa (especialmente nos níveis altos de depuração), e não será desejado salvá-la indefinidamente.
É necessário fazer a “rotação” dos arquivos de registro, para que sejam iniciados novos arquivos e os arquivos antigos
sejam removidos periodicamente.
Se for simplesmente direcionada a saída stderr do postmaster para um arquivo, haverá uma saída de registro, mas a
única maneira de truncar o arquivo de registro será parando e reiniciando o postmaster, o que pode ser adequado em
um ambiente de desenvolvimento, mas poucos ambientes de produção vão considerar esse comportamento aceitável.
Outra abordagem para gerenciar a saída do registro, apropriada para ambientes de produção, é enviar a saída para syslog
e deixar que algum programa cuide da rotação do registro. Se for desejado automatizar a rotação do registro, pode ser
configurado o programa logrotate para trabalhar com os arquivos de registro do syslog
1
.
Como para tudo que contém dados importantes, devem ser feitas cópias de segurança dos bancos de dados regularmente.
Embora o procedimento seja essencialmente simples, é importante possuir uma compreensão básica das técnicas e
princípios subjacentes.
Existem duas abordagens fundamentalmente diferentes para fazer cópia de segurança dos dados do PostgreSQL:
• Método SQL-dump.
• Cópia de segurança no nível de sistema operacional.
5. Método SQL-dump
A ideia por trás do Método SQL-dump é gerar um arquivo texto contendo comandos SQL que, ao serem processados pelo
servidor, recriam o banco de dados no mesmo estado em que esse se encontrava quando o arquivo foi gerado.
O PostgreSQL disponibiliza o programa utilitário pg_dump para essa finalidade. A forma básica de utilização desse
programa é:
pg_dump nome_do_banco_de_dados > arquivo_de_saída
Conforme pode ser visto, o programa pg_dump escreve o seu resultado na saída padrão. Será visto abaixo como isso
pode ser útil.
O pg_dump é uma aplicação cliente normal do PostgreSQL (embora seja particularmente astuta). Isso significa que o
procedimento de cópia de segurança pode ser realizado a partir de qualquer hospedeiro remoto que possua acesso ao
banco de dados. Porém, deve ser lembrado que o pg_dump não opera com permissão especial. Em particular, é necessário
possuir acesso de leitura a todas as tabelas que se deseja fazer cópia de segurança. Portanto, na prática, quase sempre
é necessário ser um superusuário do banco de dados.
Para especificar qual servidor de banco de dados o pg_dump deve se conectar devem ser utilizadas as opções de linha
de comando -h hospedeiro e -p porta. O hospedeiro padrão é o hospedeiro local, ou o que estiver especificado na variável
de ambiente PGHOST. De maneira semelhante, a porta padrão é indicada pela variável de ambiente PGPORT ou, na falta
dessa, pelo padrão de compilação.
1 Syslog é um mecanismo que permite que qualquer comando registre mensagens na console do sistema e/ou em um arquivo. O daemon syslogd recebe as mensagens dos comandos
e envia para o destino descrito no arquivo de configuração ( /etc/syslog.conf ). O syslogd daemon lê a configuração quando é inicializado e quando recebe um signal de hangup (
kill -HUP processo )
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
111
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
Assim como qualquer outra aplicação cliente do PostgreSQL, o pg_dump se conecta por padrão ao banco de dados cujo
nome é igual ao nome do usuário corrente do sistema operacional. Para que seja outro, deve ser especificada a opção
-U, ou definida a variável de ambiente PGUSER. Não deve ser esquecido que as conexões do pg_dump estão sujeitas aos
mecanismos normais de autenticação de cliente.
As cópias de segurança criadas pelo pg_dump são consistentes internamente, ou seja, as atualizações feitas no banco
de dados enquanto o pg_dump está executando não estão presentes na cópia de segurança. O pg_dump não bloqueia
outras operações no banco de dados enquanto está executando (Exceto as operações que necessitam operar com modo
de bloqueio exclusivo, como o VACUUM FULL).
Dica 1: Quando o esquema do banco de dados é dependente dos OIDs (como chaves-estrangeiras, por exemplo)
deve-se instruir o pg_dump para que também inclua os OIDs. Para que isso seja feito, deve ser utilizada
a opção de linha de comando -o. Também, não são feitas cópias de segurança dos “objetos grandes” por
padrão. Se forem utilizados objetos grandes, deve ser vista a página de referência do programa pg_dump .
5.1. Restauração da Cópia de Segurança
Os arquivos-texto criados pelo programa pg_dump são feitos para serem lidos pelo programa psql. A forma geral do
comando para restaurar uma cópia de segurança é:
psql nome_do_banco_de_dados < arquivo_de_entrada
O arquivo_de_entrada é o que foi utilizado como arquivo_de_saída pelo programa pg_dump. O banco de dados nome_
do_banco_de_dados não será criado por esse comando, devendo ser criado a partir de template0 antes de executar o
psql (por exemplo, usando createdb -T template0 nome_do_banco_de_dados). O psql possui opções semelhantes às do
pg_dump para controlar a identificação do servidor de banco de dados e o nome do usuário.
Se no banco de dados original os objetos pertencem a usuários diferentes, então a cópia de segurança instrui o psql a
se conectar como cada usuário afetado por vez, e depois a criar os objetos relevantes. Dessa forma, o dono original é
preservado. Entretanto, isso também significa que todos esses usuários devem existir, e que é possível se conectar como
cada um deles. Portanto, pode ser necessário fazer um relaxamento temporário das definições de autenticação de clientes.
Uma vez feita a restauração, é sensato executar o comando ANALYZE em cada um dos bancos de dados, para que o
otimizador possua estatísticas úteis. Uma forma fácil de fazer é executando vacuumdb -a -z para efetuar o VACUUM
ANALYZE de todos os bancos de dados; equivale a executar VACUUM ANALYZE manualmente.
A capacidade do pg_dump e do psql de escrever e ler de pipes torna possível replicar um banco de dados de um servidor
para outro diretamente; por exemplo:
pg_dump -h hospedeiro1 nome_do_banco_de_dados | psql -h hospedeiro2 nome_do_banco_de_dados
Dica 1: As cópias de segurança produzidas pelo pg_dump são relativas a template0. Isso significa que todas
as linguagens, procedimentos, etc., adicionados a template1, também serão incluídos na cópia de segurança
feita pelo pg_dump. Como resultado, se estiver sendo utilizado um banco de dados template1 personalizado,
ao ser feita a restauração deve ser criado um banco de dados vazio a partir de template0, conforme mostrado
no exemplo acima.
5.2. Utilização do pg_dumpall
O mecanismo mostrado acima não é cômodo nem apropriado para fazer a cópia de segurança de todo o agrupamento de
bancos de dados. Por esse motivo, é fornecido o programa pg_dumpall . O pg_dumpall faz a cópia de segurança de todos
os bancos de dados de um agrupamento, e também salva dados de todo o agrupamento, como os usuários e grupos. A
forma básica de utilização desse programa é:
pg_dumpall > arquivo_de_saída
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
112
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
A cópia de segurança gerada pode ser restaurada pelo psql usando:
psql template1 < arquivo_de_entrada
Na verdade, pode ser especificado qualquer nome de banco de dados existente para começar, mas se estiver sendo feita
a restauração em um agrupamento vazio, então template1 é a única escolha disponível. É sempre necessário possuir
acesso de superusuário do banco de dados para fazer a restauração de uma cópia de segurança gerada pelo pg_dumpall,
para poder restaurar as informações de usuário e de grupo.
5.3. Tratamento de Bancos de Dados Grandes
Uma vez que o PostgreSQL permite a existência de tabelas maiores do que o tamanho máximo de arquivo do sistema
operacional, pode ser problemático fazer a cópia de segurança de uma tabela como essa em um arquivo, uma vez que
o arquivo resultante provavelmente será maior do que o tamanho máximo permitido pelo sistema operacional. Como o
pg_dump pode escrever na saída padrão, podem ser utilizadas as ferramentas padrão do Unix para superar esse possível
problema.
5.3.1. Utilização de cópias de segurança comprimidas.
Pode ser utilizado o programa de compressão favorito como, por exemplo, o gzip.
pg_dump nome_do_banco_de_dados | gzip > nome_do_arquivo.gz
Restaurar com o seguinte comando:
createdb nome_do_banco_de_dados
gunzip -c nome_do_arquivo.gz | psql nome_do_banco_de_dados
ou
cat nome_do_arquivo.gz | gunzip | psql nome_do_banco_de_dados
5.3.2. Utilização do comando split.
O comando split permite dividir a saída em blocos de tamanho aceitável para o sistema de arquivos subjacente. Por
exemplo, para fazer blocos de 1 megabyte:
pg_dump nome_do_banco_de_dados | split -b 1m - nome_do_arquivo
Restaurar com
createdb nome_do_banco_de_dados
cat nome_do_arquivo* | psql nome_do_banco_de_dados
5.3.3. Utilização de formatos de cópia de segurança personalizados.
Se o PostgreSQL foi construído em um sistema com a biblioteca de compressão zlib instalada, o formato de cópia de
segurança personalizado comprime os dados ao escrever o arquivo de saída. Produz cópias de segurança com tamanhos
semelhantes às produzidas, utilizando o gzip, mas tem a vantagem adicional de permitir a restauração seletiva das
tabelas. O comando abaixo gera a cópia de segurança do banco de dados, utilizando o formato de cópia de segurança
personalizado (custom dump format):
pg_dump -Fc nome_do_banco_de_dados > nome_do_arquivo
O formato de cópia de segurança personalizado não é um script para o psql, devendo ser restaurado pelo pg_restore.
Para obter detalhes devem ser vistas as páginas de referência do pg_dump e do pg_restore .
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
113
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
5.4. Precauções
O pg_dump (e consequentemente o pg_dumpall) possui algumas poucas limitações causadas pela dificuldade de reconstruir
certas informações a partir dos catálogos do sistema.
Especificamente, a ordem utilizada pelo pg_dump para escrever os objetos não é muito sofisticada. Isso pode causar problemas
como, por exemplo, quando são utilizadas funções como valor padrão de colunas. A única solução é reorganizar manualmente
a cópia de segurança. Se forem criadas dependências circulares no esquema, então haverá mais trabalho a ser feito.
Por motivo de compatibilidade com as versões anteriores, o pg_dump não faz cópia de segurança dos objetos grandes
por padrão. Para fazer cópia de segurança dos objetos grandes deve ser utilizado o formato de saída personalizado ou o
formato tar, e utilizada a opção -b do pg_dump. Para obter detalhes deve ser vista a página de referência do pg_dump.
O diretório contrib/pg_dumplo, da árvore do código fonte do PostgreSQL, também contém um programa que pode ser
utilizado para fazer cópias de segurança dos objetos grandes.
6. Cópia de Segurança no Nível de Sistema de Arquivo
Uma estratégia alternativa para fazer cópia de segurança, é copiar diretamente os arquivos que o PostgreSQL usa para
armazenar os dados dos bancos de dados. Pode ser utilizada a forma preferida para fazer as cópias de segurança usuais
dos arquivos do sistema como, por exemplo:
tar -cf copia_de_seguranca.tar /usr/local/pgsql/data
Entretanto, existem duas restrições que fazem com que esse método seja impraticável ou, pelo menos, inferior ao pg_dump:
1. O servidor de banco de dados deve estar parado para que se possa obter uma cópia de segurança
utilizável. Meias medidas, como impedir todas as conexões, não funcionam, porque sempre existe
alguma “buferização” em andamento. Por essa razão também não é aconselhável confiar em sistemas
de arquivo que dizem suportar “instantâneos consistentes” (consistent snapshots).É desnecessário
dizer que, também, é necessário parar o servidor antes de restaurar os dados.
2. Caso tenha se aprofundado nos detalhes da organização do sistema de arquivos do banco de dados,
poderá estar tentado a fazer cópias de segurança ou restauração de apenas algumas determinadas
tabelas ou bancos de dados a partir de seus respectivos arquivos ou diretórios. Isso não funciona,
porque as informações contidas nesses arquivos possuem apenas meia verdade. A outra metade está
nos arquivos de registro de efetivação pg_clog/*, que contêm o status de efetivação de todas as
transações. O arquivo da tabela somente possui utilidade com essa informação. É claro que também
não é possível restaurar apenas uma tabela e seus dados associados em pg_clog, porque isso torna
todas as outras tabelas do agrupamento de bancos de dados inúteis. Portanto, as cópias de segurança
do sistema de arquivos somente funcionam para a restauração completa de todo o agrupamento de
bancos de dados.
Uma abordagem alternativa para cópias de segurança do sistema de arquivos é fazer um “instantâneo consistente” do
diretório de dados, se o sistema de arquivos possuir essa funcionalidade (e se há confiança que foi implementado de
forma correta). Esse tipo de instantâneo salva os arquivos do banco de dados em um estado onde o servidor de banco
de dados não foi parado de forma apropriada; portanto, quando o servidor de banco de dados é iniciado acessando um
diretório restaurado a partir de uma cópia de segurança desse tipo, considera que o servidor caiu e refaz o registro do
WAL. Isso não é um problema, mas deve-se estar atento a esse fato (e certifique-se de incluir os arquivos do WAL na
cópia de segurança).
Deve ser observado que a cópia de segurança do sistema de arquivos não será necessariamente menor que a do Método
SQL-dump. Ao contrário, é mais provável que seja maior; por exemplo, o pg_dump não necessita fazer cópia de segurança
dos índices, mas apenas dos comandos para recriá-los.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
114
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
7. Cópia de segurança em-linha
Durante todo o tempo, o PostgreSQL mantém o registro de escrita prévia (WAL = write ahead log) no subdiretório
pg_xlog do diretório de dados do agrupamento. O WAL contém todas as alterações realizadas nos arquivos de dados
do banco de dados. O WAL existe, principalmente, com a finalidade de fornecer segurança contra quedas: se o sistema
cair, o banco de dados pode retornar a um estado consistente, “refazendo” as entradas gravadas desde o último ponto
de verificação. Entretanto, a existência do WAL torna possível uma terceira estratégia para fazer cópia de segurança
de banco de dados: pode ser combinada a cópia de segurança do banco de dados, no nível de sistema de arquivos, com
cópia dos arquivos de segmento do WAL. Se for necessário fazer a recuperação, pode ser feita a recuperação da cópia
de segurança do banco de dados no nível de sistema de arquivos e, depois, refeitas as alterações a partir da cópia dos
arquivos de segmento do WAL, para trazer a restauração para o tempo presente.
A administração dessa abordagem é mais complexa que a administração das abordagens anteriores, mas existem alguns
benefícios significativos:
• O ponto de partida não precisa ser uma cópia de segurança totalmente consistente. Toda inconsistência
interna na cópia de segurança é corrigida quando o WAL é refeito (o que não é muito diferente do que
acontece durante a recuperação de uma queda). Portanto, não é necessário um sistema operacional com
capacidade de tirar instantâneos, basta apenas o tar, ou outra ferramenta semelhante.
• Como pode ser reunida uma sequência indefinidamente longa de arquivos de segmento do WAL para serem
refeitos, pode ser obtida uma cópia de segurança contínua simplesmente continuando a fazer cópias dos
arquivos de segmento do WAL. Isso é particularmente útil para bancos de dados grandes, onde pode não ser
conveniente fazer cópias de segurança completas regularmente.
• Não existe nada que diga que as entradas do WAL devem ser refeitas até o fim. Pode-se parar de refazer
em qualquer ponto, e obter um instantâneo consistente do banco de dados como se tivesse sido tirado no
instante da parada. Portanto, essa técnica suporta a recuperação para um determinado ponto no tempo:
é possível restaurar voltando o banco de dados para o estado em que se encontrava a qualquer instante
posterior ao da realização da cópia de segurança base.
• Se outra máquina, carregada com a mesma cópia de segurança base do banco de dados, for alimentada
continuamente com a série de arquivos de segmento do WAL, será criado um sistema reserva a quente (hot
standby): a qualquer instante essa outra máquina pode ser ativada com uma cópia quase atual do banco de
dados.
Da mesma forma que o método de cópia de segurança no nível de sistema de arquivos simples, esse método suporta
apenas a restauração de todo o agrupamento de bancos de dados, e não a restauração de apenas um subconjunto desse.
Requer, também, grande volume de armazenamento de arquivos: a cópia de segurança base pode ser grande, e um sistema
carregado gera vários megabytes de tráfego para o WAL que precisam ser guardados. Ainda assim, é o método de cópia
de segurança preferido para muitas situações onde é necessária uma alta confiabilidade.
Para fazer uma recuperação bem-sucedida utilizando cópia de segurança em-linha, é necessária uma sequência contínua de
arquivos de segmento do WAL guardados, que venha desde, pelo menos, o instante em que foi feita a cópia de segurança
base do banco de dados. Para começar, deve ser configurado e testado o procedimento para fazer cópia dos arquivos de
segmento do WAL, antes de ser feita a cópia de segurança base do banco de dados. Assim sendo, primeiro será explicada
a mecânica para fazer cópia dos arquivos de segmento do WAL.
7.1. Cópia dos arquivos de segmento do WAL
Em um sentido abstrato, a execução do sistema PostgreSQL produz uma sequência indefinidamente longa de entradas
no WAL. O sistema divide fisicamente essa sequência em arquivos de segmento do WAL, normalmente com 16 MB cada
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
115
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
(embora o tamanho possa ser alterado durante a construção do PostgreSQL). São atribuídos nomes numéricos aos arquivos
de segmento para refletir sua posição na sequência abstrata do WAL. Quando não é feita cópia dos arquivos de segmento
do WAL, normalmente o sistema cria apenas uns poucos arquivos de segmento e, depois, “recicla-os”, renomeando os
arquivos que não são mais de interesse com número de segmento mais alto. Assume-se não existir mais interesse em um
arquivo de segmento cujo conteúdo preceda o ponto de verificação anterior ao último, podendo, portanto, ser reciclado.
Quando é feita a cópia dos arquivos de segmento do WAL, deseja-se capturar o conteúdo de cada arquivo quando esse é
completado, guardando os dados em algum lugar antes do arquivo de segmento ser reciclado para ser reutilizado.
Dependendo da aplicação e dos periféricos disponíveis, podem haver muitas maneiras de “guardar os dados em algum
lugar”: os arquivos de segmento podem ser copiados para outra máquina usando um diretório NFS montado, podem ser
escritos em uma unidade de fita (havendo garantia que os arquivos poderão ser restaurados com seus nomes originais),
podem ser agrupados e gravados em CD, ou de alguma outra forma. Para que o administrador de banco de dados tenha a
máxima flexibilidade possível, o PostgreSQL tenta não assumir nada sobre como as cópias serão feitas. Em vez disso, o
PostgreSQL deixa o administrador escolher o comando a ser executado para copiar o arquivo de segmento completado para
o local de destino. O comando pode ser tão simples como cp, ou pode envolver um script complexo para o interpretador
de comandos — tudo depende do administrador.
O comando a ser executado é especificado por meio do parâmetro de configuração archive_command, que, na prática, é
sempre colocado no arquivo postgresql.conf. Na cadeia de caracteres do comando, todo %p é substituído pelo caminho
absoluto do arquivo a ser copiado, enquanto todo %f é substituído pelo nome do arquivo apenas. Se for necessário
incorporar o caractere % ao comando, deve ser escrito %%. A forma mais simples de um comando útil é algo como:
archive_command = ‘cp -i %p /mnt/servidor/dir_copias/%f </dev/null’
Esse comando irá copiar os arquivos de segmento do WAL, prontos para serem copiados, para o diretório /mnt/servidor/
dir_copias (Isso é um exemplo, e não uma recomendação, e pode não funcionar em todas as plataformas).
O comando para realizar a cópia é executado sob a propriedade do mesmo usuário que está executando o servidor
PostgreSQL. Como a série de arquivos do WAL contém efetivamente tudo que está no banco de dados, deve haver
certeza que a cópia está protegida contra olhos curiosos; por exemplo, colocando a cópia em diretório sem acesso para
grupo ou para todos.
É importante que o comando para realizar a cópia retorne o status de saída zero se, e somente se, for bem-sucedido. Ao
receber o resultado zero, o PostgreSQL assume que a cópia do arquivo de segmento do WAL foi bem-sucedida, e remove
ou recicla o arquivo de segmento. Entretanto, um status diferente de zero informa ao PostgreSQL que o arquivo não foi
copiado; serão feitas tentativas periódicas até ser bem-sucedida.
Geralmente o comando de cópia deve ser projetado de tal forma que não sobrescreva algum arquivo de cópia preexistente.
Essa é uma característica de segurança importante para preservar a integridade da cópia no caso de um erro do
administrador (tal como enviar a saída de dois servidores diferentes para o mesmo diretório de cópias). Aconselha-se a
testar o comando de cópia proposto para ter certeza que não sobrescreve um arquivo existente, e que retorna um status
diferente de zero nesse caso. Tem sido observado que cp -i faz isso corretamente em algumas plataformas, mas não em
outras. Se o comando escolhido não tratar esse caso corretamente por conta própria, deve ser adicionado um comando
para testar a existência do arquivo de cópia. Por exemplo, algo como:
archive_command = ‘test ! -f .../%f && cp %p .../%f’
Ao projetar a configuração de cópia deve ser considerado o que vai acontecer quando o comando de cópia falhar repetidas
vezes, seja porque alguma funcionalidade requer intervenção do operador, ou porque não há espaço para armazenar a
cópia. Essa situação pode ocorrer, por exemplo, quando a cópia é escrita em fita e não há um sistema automático para
troca de fitas: quando a fita ficar cheia, não será possível fazer outras cópias enquanto não for trocada. Deve-se garantir
que qualquer condição de erro, ou solicitação feita a um operador humano, seja relatada de forma apropriada para que
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
116
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
a situação possa ser resolvida o mais rápido possível. Enquanto a situação não for resolvida, continuarão sendo criados
novos arquivos de segmento do WAL no diretório pg_xlog.
A velocidade do comando de cópia não é importante, desde que possa acompanhar a taxa média de geração de dados
para o WAL. A operação normal prossegue mesmo que o processo de cópia fique um pouco atrasado. Se o processo de
cópia ficar muito atrasado, vai aumentar a quantidade de dados perdidos caso ocorra um desastre. Significa, também,
que o diretório pg_xlog vai conter um número grande de arquivos de segmento que ainda não foram copiados, podendo,
inclusive, exceder o espaço livre em disco. Aconselha-se que o processo de cópia seja monitorado para garantir que
esteja funcionando da forma planejada.
Havendo preocupação em se poder recuperar até o presente instante, devem ser efetuados passos adicionais para garantir
que o arquivo de segmento do WAL corrente, parcialmente preenchido, também seja copiado para algum lugar. Isso é
particularmente importante no caso do servidor gerar pouco tráfego para o WAL (ou tiver períodos ociosos onde isso
acontece), uma vez que pode levar muito tempo até que o arquivo de segmento fique totalmente preenchido e pronto para
ser copiado. Uma forma possível de tratar essa situação é definir uma entrada no cron [1] que, periodicamente, talvez
uma vez por minuto, identifique o arquivo de segmento do WAL corrente e o guarde em algum lugar seguro. Então, a
combinação dos arquivos de segmento do WAL guardados, com o arquivo de segmento do WAL corrente guardado, será
suficiente para garantir que o banco de dados pode ser restaurado até um minuto, ou menos, antes do presente instante.
Atualmente esse comportamento não está presente no PostgreSQL, porque não se deseja complicar a definição de
archive_command requerendo que esse acompanhe cópias bem-sucedidas, mas diferentes, do mesmo arquivo do WAL. O
archive_command é chamado apenas para segmentos do WAL completados. Exceto no caso de novas tentativas devido
à falha, só é chamado uma vez para um determinado nome de arquivo.
Ao escrever o comando de cópia, deve ser assumido que os nomes dos arquivos a serem copiados podem ter comprimento
de até 64 caracteres, e que podem conter qualquer combinação de letras ASCII, dígitos e pontos. Não é necessário
recordar o caminho original completo (%p), mas é necessário recordar o nome do arquivo (%f).
Deve ser lembrado que embora a cópia do WAL permita restaurar toda modificação feita nos dados dos bancos de dados do
PostgreSQL, não restaura a alterações feitas nos arquivos de configuração (ou seja, nos arquivos postgresql.conf, pg_hba.
conf e pg_ident.conf), uma vez que esses arquivos são editados manualmente, em vez de por meio de operações SQL.
O procedimento para fazer a cópia de segurança base é relativamente simples:
1. Garantir que a cópia dos arquivos de segmento do WAL esteja ativada e funcionando.
2. Conectar ao banco de dados como um superusuário e executar o comando.
3. Utiliza SELECT pg_start_backup(‘rótulo’); onde rótulo é qualquer cadeia de caracteres que se deseje
usar para identificar unicamente essa operação de cópia de segurança (Uma boa prática é utilizar o
caminho completo de onde se deseja colocar o arquivo de cópia de segurança). A função pg_start_backup
cria o arquivo rótulo da cópia de segurança, chamado backup_label, com informações sobre a cópia de
segurança, no diretório do agrupamento. Para executar esse comando, não importa qual banco de dados
do agrupamento é usado para fazer a conexão. O resultado retornado pela função pode ser ignorado;
mas se for relatado um erro, esse deve ser tratado antes de prosseguir.
4. Realizar a cópia de segurança utilizando qualquer ferramenta conveniente para cópia de segurança do
sistema de arquivos, como tar ou cpio. Não é necessário, nem desejado, parar a operação normal do
banco de dados enquanto a cópia é feita.
5. Conectar novamente ao banco de dados como um superusuário e executar o comando: SELECT
pg_stop_backup(); Se a execução for bem sucedida, está terminado.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
117
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
Não é necessário ficar muito preocupado com o tempo decorrido entre a execução de pg_start_backup e o início da
realização da cópia de segurança, nem entre o fim da realização da cópia de segurança e a execução de pg_stop_backup;
uns poucos minutos de atraso não vão criar nenhum problema. Entretanto, deve haver certeza que as operações são
realizadas sequencialmente, sem que haja sobreposição.
Deve haver certeza que a cópia de segurança inclui todos os arquivos sob o diretório do agrupamento de bancos de
dados (por exemplo, /usr/local/pgsql/data). Se estiverem sendo utilizados espaços de tabelas que não residem sob esse
diretório, deve-se ter o cuidado de incluí-los também (e ter certeza que a cópia de segurança guarda vínculos simbólicos
como vínculos, senão a restauração vai danificar os espaços de tabelas).
Entretanto, podem ser omitidos da cópia de segurança os arquivos sob o subdiretório pg_xlog do diretório do agrupamento.
Essa pequena complicação a mais vale a pena ser feita porque reduz o risco de erros na restauração. É fácil de ser feito
se pg_xlog for um vínculo simbólico apontando para algum lugar fora do agrupamento, o que é uma configuração comum
por razões de desempenho.
Para poder utilizar essa cópia de segurança base, devem ser mantidas por perto todas as cópias dos arquivos de segmento
do WAL gerados no momento ou após o início da mesma. Para ajudar a realizar essa tarefa, a função pg_stop_backup
cria o arquivo de histórico de cópia de segurança, que é armazenado imediatamente na área de cópia do WAL. Esse
arquivo recebe um nome derivado do primeiro arquivo de segmento do WAL, que é necessário possuir para fazer uso da
cópia de segurança.
Por exemplo, se o arquivo do WAL tiver o nome 0000000100001234000055CD, o arquivo de histórico de cópia de
segurança vai ter um nome parecido com 0000000100001234000055CD.007C9330.backup. A segunda parte do nome
do arquivo representa a posição exata dentro do arquivo do WAL, podendo normalmente ser ignorada.
Uma vez que o arquivo contendo a cópia de segurança base tenha sido guardado em local seguro, podem ser apagados
todos os arquivos de segmento do WAL com nomes numericamente precedentes a esse número. O arquivo de histórico
de cópia de segurança é apenas um pequeno arquivo texto. Contém a cadeia de caracteres rótulo fornecida à função
pg_start_backup, assim como as horas de início e fim da cópia de segurança. Se o rótulo for utilizado para identificar
onde está armazenada a cópia de segurança base do banco de dados, então basta o arquivo de histórico de cópia de
segurança para se saber qual é o arquivo de cópia de segurança a ser restaurado, no caso disso precisar ser feito.
Uma vez que é necessário manter por perto todos os arquivos de segmento do WAL copiados desde a última cópia de
segurança base, o intervalo entre essas cópias de segurança geralmente deve ser escolhido tendo por base quanto
armazenamento se deseja consumir para os arquivos do WAL guardados.
Também deve ser considerado quanto tempo se está preparado para despender com a restauração, no caso de ser
necessário fazer uma restauração — o sistema terá que refazer todos os segmentos do WAL, o que pode ser muito
demorado se tiver sido decorrido muito tempo desde a última cópia de segurança base.
Também vale a pena notar que a função pg_start_backup cria no diretório do agrupamento de bancos de dados um
arquivo chamado backup_label, que depois é removido pela função pg_stop_backup. Esse arquivo fica guardado como
parte do arquivo de cópia de segurança base. O arquivo rótulo de cópia de segurança inclui a cadeia de caracteres rótulo
fornecida para a função pg_start_backup, assim como a hora em que pg_start_backup foi executada, e o nome do
arquivo de segmento inicial do WAL. Em caso de dúvida, é possível olhar dentro do arquivo de cópia de segurança base
e determinar com exatidão de qual sessão de cópia de segurança esse arquivo provém.
Também é possível fazer a cópia de segurança base enquanto o postmaster está parado. Nesse caso, obviamente não
podem ser utilizadas as funções pg_start_backup e pg_stop_backup, sendo responsabilidade do administrador controlar a
que cópia de segurança cada arquivo pertence, e até quanto tempo atrás os arquivos de segmento do WAL associados vão.
Geralmente é melhor seguir os procedimentos para cópia de segurança mostrados acima.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
118
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
7.2. Recuperação a partir de cópia de segurança em-linha
Suponhamos que seja necessário recuperar a partir da cópia de segurança. O procedimento está mostrado abaixo:
1. Parar o postmaster, se estiver executando.
2. Copiar, se houver espaço para isso, todo o diretório de dados do agrupamento, e todos os espaços de
tabelas, para um lugar temporário, para o caso de necessidade. Deve ser observado que essa medida
de precaução requer que haja espaço no sistema suficiente para manter duas cópias do banco de
dados existente. Se não houver espaço suficiente, é necessário pelo menos uma cópia do conteúdo do
subdiretório pg_xlog do diretório de dados do agrupamento, porque pode conter arquivos de segmento
do WAL que não foram copiados quando o sistema parou.
3. Apagar todos os arquivos e subdiretórios existentes sob o diretório de dados do agrupamento, e sob os
diretórios raiz dos espaços de tabelas em uso.
4. Restaurar os arquivos do banco de dados a partir da cópia de segurança base. Deve-se tomar cuidado
para que sejam restaurados com o dono correto (o usuário do sistema de banco de dados, e não o
usuário root), e com as permissões corretas. Se estiverem sendo utilizados espaços de tabelas, deve
ser verificado se foram restaurados corretamente os vínculos simbólicos no subdiretório pg_tblspc/.
5. Remover todos os arquivos presentes no subdiretório pg_xlog; porque esses vêm da cópia de segurança
base e, portanto, provavelmente estão obsoletos. Se o subdiretório pg_xlog não fizer parte da cópia
de segurança base, então esse subdiretório deve ser criado, assim como o subdiretório pg_xlog/
archive_status.
6. Copiar para o diretório pg_xlog, arquivos de segmento do WAL, porventura existentes e que não foram
copiados para o diretório de cópias, mas que foram salvos no passo 2; é melhor copiá-los em vez de
movê-los, para que ainda existam arquivos não modificados, caso ocorra algum problema e o processo
tenha de ser recomeçado.
7. Criar o arquivo de comando de recuperação recovery.conf no diretório de dados do agrupamento (consulte
Recovery Settings). Também pode ser útil modificar temporariamente o arquivo pg_hba.conf, para impedir
que os usuários comuns se conectem até que se tenha certeza que a recuperação foi bem-sucedida.
8. Iniciar o postmaster. O postmaster vai entrar no modo de recuperação e prosseguir lendo os arquivos do
WAL necessários. Após o término do processo de recuperação, o postmaster muda o nome do arquivo
recovery.conf para recovery.done (para impedir que entre novamente no modo de recuperação no caso
de uma queda posterior), e depois começa as operações normais de banco de dados.
9. Deve ser feita a inspeção do conteúdo do banco de dados para garantir que a recuperação foi feita
até onde deveria ser feita. Caso contrário, deve-se retornar ao passo 1. Se tudo correu bem, liberar o
acesso aos usuários retornando pg_hba.conf à sua condição normal.
A parte chave de todo esse procedimento é a definição do arquivo contendo o comando de recuperação, que descreve
como se deseja fazer a recuperação, e até onde a recuperação deve ir. Pode ser utilizado o arquivo recovery.conf.sample
(geralmente presente no diretório de instalação share) na forma de um protótipo
1
.
O único parâmetro requerido no arquivo recovery.conf é restore_command, que informa ao PostgreSQL como trazer de
volta os arquivos de segmento do WAL copiados. Como no archive_command, esse parâmetro é uma cadeia de caracteres
para o interpretador de comandos. Pode conter %f, que é substituído pelo nome do arquivo do WAL a ser trazido de volta,
e %p, que é substituído pelo caminho absoluto para onde o arquivo do WAL será copiado. Se for necessário incorporar o
caractere % ao comando, deve ser escrito %%. A forma mais simples de um comando útil é algo como:
1 O arquivo recovery.conf.sample está presente no diretório /src/backend/access/transam da distribuição do código fonte e do CVS. (N. do T.)
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
119
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
restore_command = ‘cp /mnt/servidor/dir_copias/%f %p’
Esse comando irá copiar os arquivos de segmento do WAL previamente guardados a partir do diretório /mnt/servidor/
dir_copias. É claro que pode ser utilizado algo muito mais complicado, talvez um script que solicite ao operador a
montagem da fita apropriada.
É importante que o comando retorne um status de saída diferente de zero em caso de falha. Será solicitado ao comando
os arquivos do WAL cujos nomes não estejam presente entre as cópias; deve retornar um status diferente de zero quando
for feita a solicitação. Essa não é uma condição de erro. Deve-se tomar cuidado para que o nome base do caminho %p
seja diferente de %f; não deve ser esperado que sejam intercambiáveis.
Os arquivos de segmento do WAL que não puderem ser encontrados entre as cópias, serão procurados no diretório pg_xlog/;
isto permite que os arquivos de segmento recentes, ainda não copiados, sejam utilizados. Entretanto, os arquivos de
segmento que estiverem entre as cópias terão preferência sobre os arquivos em pg_xlog. O sistema não sobrescreve os
arquivos presentes em pg_xlog quando busca os arquivos guardados.
Normalmente, a recuperação prossegue por meio de todos os arquivos de segmento do WAL, portanto restaurando o banco
de dados até o presente momento (ou tão próximo quanto se pode chegar utilizando os segmentos do WAL). Mas se for
necessário recuperar até algum ponto anterior no tempo (digamos, logo antes do DBA júnior ter apagado a tabela principal
de transação de alguém), deve-se simplesmente especificar no arquivo recovery.conf o ponto de parada requerido. O ponto
de parada, conhecido como “destino da recuperação”, pode ser especificado tanto pela data e hora quanto pelo término
de um ID de transação específico. Até o momento em que este manual foi escrito, somente podia ser utilizada a opção
data e hora, pela falta de ferramenta para ajudar a descobrir com precisão o identificador de transação a ser utilizado.
Dica 1: O ponto de parada deve estar situado após o momento de término da cópia de segurança base (o
momento em que foi executada a função pg_stop_backup). A cópia de segurança não pode ser utilizada
para recuperar até um momento em que a cópia de segurança base estava em andamento (Para recuperar
até esse ponto, deve-se retornar para uma cópia de segurança base anterior e refazer a partir dessa cópia).
7.2.1. Definições de recuperação
Essas definições somente podem ser feitas no arquivo recovery.conf, e são aplicadas apenas durante a recuperação. As
definições deverão ser definidas novamente nas próximas recuperações que se desejar realizar. As definições não podem
ser alteradas após a recuperação ter começado.
1. restore_command (string): O comando, para o interpretador de comandos, a ser executado para trazer
de volta os segmentos da série de arquivos do WAL guardados. Esse parâmetro é requerido. Todo %f
presente na cadeia de caracteres é substituído pelo nome do arquivo a ser trazido de volta das cópias,
e todo %p é substituído pelo caminho absoluto para onde o arquivo será copiado no servidor. Se for
necessário incorporar o caractere % ao comando, deve ser escrito %%. É importante que o comando
retorne o status de saída zero se, e somente se, for bem-sucedido. Será solicitado ao comando os
arquivos cujos nomes não estejam presentes entre as cópias; deve retornar um status diferente de zero
quando for feita a solicitação.
2. recovery_target_time (timestamp): Esse parâmetro especifica o caminho do tempo até onde a
recuperação deve prosseguir. Somente pode ser especificado um entre recovery_target_time e
recovery_target_xid. O padrão é recuperar até o fim do WAL. O ponto de parada preciso também é
influenciado por recovery_target_inclusive.
3. recovery_target_xid (string): Esse parâmetro especifica o identificador de transação até onde a
recuperação deve prosseguir. Deve-se ter em mente que enquanto os identificadores são atribuídos
sequencialmente no início da transação, as transações podem ficar completas em uma ordem numérica
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
120
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
diferente. As transações que serão recuperadas são aquelas que foram efetivadas antes (e opcionalmente
incluindo) da transação especificada. Somente pode ser especificado um entre recovery_target_xid e
recovery_target_time. O padrão é recuperar até o fim do WAL. O ponto de parada preciso também é
influenciado por recovery_target_inclusive.
4. recovery_target_inclusive (boolean): Especifica se a parada deve acontecer logo após o destino de
recuperação especificado (true), ou logo antes do destino de recuperação especificado (false). Aplica-
se tanto a recovery_target_time quanto a recovery_target_xid, o que for especificado para essa
recuperação. Indica se as transações que possuem exatamente a hora de efetivação ou o identificador
de destino, respectivamente, serão incluídas na recuperação. O valor padrão é true.
5. recovery_target_timeline (string): Especifica a recuperação de uma determinada cronologia. O padrão
é recuperar ao longo da cronologia que era a cronologia corrente quando foi feita a cópia de segurança
base. Somente será necessário definir esse parâmetro em situações de re-recuperações complexas,
onde é necessário retornar para um estado a que se chegou após uma recuperação para um ponto no
tempo.
7.3. Cronologias
A capacidade de restaurar um banco de dados para um determinado ponto anterior no tempo cria algumas complexidades
que são semelhantes às das narrativas de ficção científica sobre viagem no tempo e universos paralelos. Por exemplo,
na história original do banco de dados talvez tenha sido removida uma tabela importante às 5:15 da tarde de terça-feira.
Imperturbável, o administrador pega a cópia de segurança e faz uma restauração para o ponto no tempo 5:14 da tarde
de terça feira, e o sistema volta a funcionar. Nessa história do universo do banco de dados, a tabela nunca foi removida.
Mas suponha que mais tarde seja descoberto que essa não foi uma boa ideia, e que se deseja voltar para algum ponto
posterior da história original. Mas isso não poderá ser feito, porque quando o banco de dados foi posto em atividade
esse sobrescreveu alguns dos arquivos de segmento do WAL que levariam ao ponto no tempo onde agora quer se chegar.
Portanto, realmente é necessário fazer distinção entre a série de entradas no WAL geradas após a recuperação para um
ponto no tempo, e aquelas geradas durante a história original do banco de dados.
Para lidar com esses problemas, o PostgreSQL possui a noção de cronologias (timelines). Cada vez que é feita uma
recuperação no tempo anterior ao fim da sequência do WAL, é criada uma nova cronologia para identificar a série de
registros do WAL geradas após a recuperação (entretanto, se a recuperação prosseguir até o final do WAL, não é criada
uma nova cronologia: apenas se estende a cronologia existente). O número identificador da cronologia é parte dos
nomes dos arquivos de segmento do WAL e, portanto, uma nova cronologia não sobrescreve os dados do WAL gerados
pelas cronologias anteriores. É possível, na verdade, guardar muitas cronologias diferentes. Embora possa parecer uma
funcionalidade sem utilidade, muitas vezes é de grande valia. Considere a situação onde não se tem certeza absoluta de
até que ponto no tempo deve ser feita a recuperação e, portanto, devem ser feitas muitas tentativas de recuperação até
ser encontrado o melhor lugar para se desviar da história antiga. Sem as cronologias, esse processo em pouco tempo
cria uma confusão impossível de ser gerenciada. Com as cronologias, pode ser feita a recuperação até qualquer estado
anterior, inclusive os estados no desvio de cronologia abandonados posteriormente.
Toda vez que é criada uma nova cronologia, o PostgreSQL cria um arquivo de “história da cronologia”, que mostra de
que cronologia foi feito o desvio, e quando. Os arquivos de cronologia são necessários para permitir o sistema buscar
os arquivos de segmento do WAL corretos ao fazer a recuperação a partir de uma área de cópias que contém várias
cronologias. Portanto, esses arquivos são guardados na área de cópias como qualquer arquivo de segmento do WAL. Os
arquivos de cronologia são apenas pequenos arquivos-texto sendo, portanto, barato e apropriado mantê-los guardados
indefinidamente (ao contrário dos arquivos de segmento que são grandes). É possível, caso se deseje fazê-lo, adicionar
comentários aos arquivos de cronologia para fazer anotações personalizadas sobre como e porque foi criada uma
determinada cronologia. Esses comentários são muito úteis quando há um grande número de cronologias criadas como
resultado de experiências.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
121
Armazenamento de Dados, Indexação, Processamento de Consultas e Projeto Físico Unidade IV
O comportamento padrão de recuperação é fazê-lo ao longo da cronologia, que era a cronologia corrente quando foi feita
a cópia de segurança base. Se for desejado executar a recuperação utilizando uma cronologia filha (ou seja, deseja-se
retornar para algum estado que foi gerado após uma tentativa de recuperação), é necessário especificar o identificador
da cronologia de destino no arquivo recovery.conf. Não é possível fazer a recuperação para um estado que foi um desvio
anterior à cópia de segurança base.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
122
Para (não) Finalizar
Ao chegarmos ao final da disciplina, esperamos que os conhecimentos aqui transcritos e os trabalhos desenvolvidos
tenham contribuído no sentido de incrementar suas habilidades no trato com Sistemas de Gerenciamento de Banco de
Dados, bem como para despertar para a importância do tema.
No intuito de aprimorarmos o nosso trabalho, solicitamos que sejam enviadas sugestões ou críticas sobre a disciplina
para o tutor.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
123
Referências
ALVES, W. P. Fundamentos de banco de dados. 1. Ed. São Paulo: Érica, 2004
CODD, E. F. A relational model of data for large shared data banks. Revista CACM volume = 6,1970
_____. Further normalization of the data base relational model, In: Rustin [1972], pg 33-64 (1972).
DATE, C. J. Introdução a sistemas de bancos de dados. Rio de Janeiro: Campus, 1983.
ELMASRI, R. Sistema de banco de dados - Fundamentos e Aplicações, 4. Ed. s/l: Pearson Education, s/d.
HEUSER, C. A. Projeto de banco de dados, 4. ed. Porto Alegre: Livros Didáticos, Porto Alegre, 2001
_____. Projeto de banco de dados. Porto Alegre: Sagra Luzzatto, 2000.
KORTH, H. F.; SILBERSCHATZ, A. Sistema de banco de dados. São Paulo: Makron Books, 1995.
KROENKE, D. M. Banco de dados – fundamentos, projeto e implementação. Rio de Janeiro: LTC, 1998.
MACHADO, F. Projeto de banco de dados. São Paulo: Érica, 1996
MECENAS, I. Banco de dados: do modelo conceitual à implementação física. Rio de Janeiro: Alta Books, 2005.
NADEAU, T.; LIGHTSTONE, S.; TEOREY, T. Projeto e modelagem de bancos de dados, 4. Ed. Campus/Elsevier.
OPPEL, A. Banco de dados desmistificado. Rio de Janeiro: Alta Books, 2004
RAMALHO, J. A. A.. SQL: A Linguagem dos bancos de dados. São Paulo: Berkeley Brasil, 1999.
SETZER, V. W. Banco de dados. São Paulo: Edgard Blücher, 1990.
SQL Language – Oracle reference manual; Version 7.2
SUDARSHAN, S.; SILBERSCHATZ, A.; KORTH, F.H. Sistemas de banco de dados. 3. Ed. S. Paulo: Makron Books,
1999
TAKAI, O. K.; ITALIANO, I. C.; FERREIRA, J. E. Introdução a banco de dados. São Paulo: DCC/IME/USP, 2005.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
124
Apêndice I
Apêndice I – Palavras-Chave do SQL
A Tabela I.1 lista todos os termos (tokens) que são palavras-chave no padrão SQL. O padrão SQL faz distinção entre
palavras-chave reservadas e não reservadas. De acordo com o padrão, as reservadas são as únicas palavras-chave reais;
nunca são permitidas como identificadores. As não reservadas somente possuem significado especial em determinados
contextos; podem ser utilizadas como identificador em outros contextos. Em sua maior parte, as palavras-chave não
reservadas são, na verdade, nomes de tabelas e funções nativas especificadas pelo padrão SQL.
Essencialmente, o conceito de palavra-chave não reservada existe apenas para declarar a associação dessa palavra com
um significado predefinido em alguns contextos.
Existem algumas palavras-chave não reservadas que não podem ser utilizadas como nome de função ou de tipo de dado,
estando devidamente indicado. Em sua maioria, essas palavras representam funções nativas ou tipos de dado com sintaxe
especial. A função ou o tipo ainda está disponível, mas não pode ser redefinido pelo usuário. Na coluna “reservada”
estão os termos permitidos apenas como títulos de coluna utilizando “AS” e, talvez, em muito poucos outros contextos.
Algumas palavras-chave reservadas são permitidas como nome de função; isso também está indicado na tabela.
Como regra geral, se acontecerem erros indevidos do analisador em comandos contendo como identificador qualquer
uma das palavras-chave listadas, deve-se tentar colocar o identificador entre aspas para ver se o problema desaparece.
Palavra-chave SQL 99 SQL 92
ABORT
ABS não reservada
ABSOLUTE reservada reservada
ACCESS
ACTION reservada reservada
ADA não reservada não reservada
ADD reservada reservada
ADMIN reservada
AFTER reservada
AGGREGATE reservada
ALIAS reservada
ALL reservada reservada
ALLOCATE reservada reservada
ALTER reservada reservada
ANALYSE
ANALYZE
AND reservada reservada
ANY reservada reservada
ARE reservada reservada
ARRAY reservada
AS reservada reservada
ASC reservada reservada
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
125
Apêndice I
Palavra-chave SQL 99 SQL 92
ASENSITIVE não reservada
ASSERTION reservada reservada
ASSIGNMENT não reservada
ASYMMETRIC não reservada
AT reservada reservada
ATOMIC não reservada
AUTHORIZATION reservada reservada
AVG não reservada reservada
BACKWARD
BEFORE reservada
BEGIN reservada reservada
BETWEEN não reservada reservada
BIGINT
BINARY reservada
BIT reservada reservada
BITVAR não reservada
BIT_LENGTH não reservada reservada
BLOB reservada
BOOLEAN reservada
BOTH reservada reservada
BREADTH reservada
BY reservada reservada
C não reservada não reservada
CACHE
CALL reservada
CALLED não reservada
CARDINALITY não reservada
CASCADE reservada reservada
CASCADED reservada reservada
CASE reservada reservada
CAST reservada reservada
CATALOG reservada reservada
CATALOG_NAME não reservada não reservada
CHAIN não reservada
CHAR reservada reservada
CHARACTER reservada reservada
CHARACTERISTICS
CHARACTER_LENGTH não reservada reservada
CHARACTER_SET_CATALOG não reservada não reservada
CHARACTER_SET_NAME não reservada não reservada
CHARACTER_SET_SCHEMA não reservada não reservada
CHAR_LENGTH não reservada reservada
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
126
Apêndice I
Palavra-chave SQL 99 SQL 92
CHECK reservada reservada
CHECKED não reservada
CHECKPOINT
CLASS reservada
CLASS_ORIGIN não reservada não reservada
CLOB reservada
CLOSE reservada reservada
CLUSTER
COALESCE não reservada reservada
COBOL não reservada não reservada
COLLATE reservada reservada
COLLATION reservada reservada
COLLATION_CATALOG não reservada não reservada
COLLATION_NAME não reservada não reservada
COLLATION_SCHEMA não reservada não reservada
COLUMN reservada reservada
COLUMN_NAME não reservada não reservada
COMMAND_FUNCTION não reservada não reservada
COMMAND_FUNCTION_CODE não reservada
COMMENT
COMMIT reservada reservada
COMMITTED não reservada não reservada
COMPLETION reservada
CONDITION_NUMBER não reservada não reservada
CONNECT reservada reservada
CONNECTION reservada reservada
CONNECTION_NAME não reservada não reservada
CONSTRAINT reservada reservada
CONSTRAINTS reservada reservada
CONSTRAINT_CATALOG não reservada não reservada
CONSTRAINT_NAME não reservada não reservada
CONSTRAINT_SCHEMA não reservada não reservada
CONSTRUCTOR reservada
CONTAINS não reservada
CONTINUE reservada reservada
CONVERSION
CONVERT não reservada reservada
COPY
CORRESPONDING reservada reservada
COUNT não reservada reservada
CREATE reservada reservada
CREATEDB
CREATEUSER
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
127
Apêndice I
Palavra-chave SQL 99 SQL 92
CROSS reservada reservada
CUBE reservada
CURRENT reservada reservada
CURRENT_DATE reservada reservada
CURRENT_PATH reservada
CURRENT_ROLE reservada
CURRENT_TIME reservada reservada
CURRENT_TIMESTAMP reservada reservada
CURRENT_USER reservada reservada
CURSOR reservada reservada
CURSOR_NAME não reservada não reservada
CYCLE reservada
DATA reservada não reservada
DATABASE
DATE reservada reservada
DATETIME_INTERVAL_CODE não reservada não reservada
DATETIME_INTERVAL_PRECISION não reservada não reservada
DAY reservada reservada
DEALLOCATE reservada reservada
DEC reservada reservada
DECIMAL reservada reservada
DECLARE reservada reservada
DEFAULT reservada reservada
DEFAULTS
DEFERRABLE reservada reservada
DEFERRED reservada reservada
DEFINED não reservada
DEFINER não reservada
DELETE reservada reservada
DELIMITER
DELIMITERS
DEPTH reservada
DEREF reservada
DESC reservada reservada
DESCRIBE reservada reservada
DESCRIPTOR reservada reservada
DESTROY reservada
DESTRUCTOR reservada
DETERMINISTIC reservada
DIAGNOSTICS reservada reservada
DICTIONARY reservada
DISCONNECT reservada reservada
DISPATCH não reservada
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
128
Apêndice I
Palavra-chave SQL 99 SQL 92
DISTINCT reservada reservada
DO
DOMAIN reservada reservada
DOUBLE reservada reservada
DROP reservada reservada
DYNAMIC reservada
DYNAMIC_FUNCTION não reservada não reservada
DYNAMIC_FUNCTION_CODE não reservada
EACH reservada
ELSE reservada reservada
ENCODING
ENCRYPTED
END reservada reservada
END-EXEC reservada reservada
EQUALS reservada
ESCAPE reservada reservada
EVERY reservada
EXCEPT reservada reservada
EXCEPTION reservada reservada
EXCLUDING
EXCLUSIVE
EXEC reservada reservada
EXECUTE reservada reservada
EXISTING não reservada
EXISTS não reservada reservada
EXPLAIN
EXTERNAL reservada reservada
EXTRACT não reservada reservada
FALSE reservada reservada
FETCH reservada reservada
FINAL não reservada
FIRST reservada reservada
FLOAT reservada reservada
FOR reservada reservada
FORCE
FOREIGN reservada reservada
FORTRAN não reservada não reservada
FORWARD
FOUND reservada reservada
FREE reservada
FREEZE
FROM reservada reservada
FULL reservada reservada
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
129
Apêndice I
Palavra-chave SQL 99 SQL 92
FUNCTION reservada
G não reservada
GENERAL reservada
GENERATED não reservada
GET reservada reservada
GLOBAL reservada reservada
GO reservada reservada
GOTO reservada reservada
GRANT reservada reservada
GRANTED não reservada
GROUP reservada reservada
GROUPING reservada
HANDLER
HAVING reservada reservada
HIERARCHY não reservada
HOLD não reservada
HOST reservada
HOUR reservada reservada
IDENTITY reservada reservada
IGNORE reservada
ILIKE
IMMEDIATE reservada reservada
IMMUTABLE
IMPLEMENTATION não reservada
IMPLICIT
IN reservada reservada
INCLUDING
INCREMENT
INDEX
INDICATOR reservada reservada
INFIX não reservada
INHERITS
INITIALIZE reservada
INITIALLY reservada reservada
INNER reservada reservada
INOUT reservada
INPUT reservada reservada
INSENSITIVE não reservada reservada
INSERT reservada reservada
INSTANCE não reservada
INSTANTIABLE não reservada
INSTEAD
INT reservada reservada
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
130
Apêndice I
Palavra-chave SQL 99 SQL 92
INTEGER reservada reservada
INTERSECT reservada reservada
INTERVAL reservada reservada
INTO reservada reservada
INVOKER não reservada
IS reservada reservada
ISNULL
ISOLATION reservada reservada
ITERATE reservada
JOIN reservada reservada
K não reservada
KEY reservada reservada
KEY_MEMBER não reservada
KEY_TYPE não reservada
LANCOMPILER
LANGUAGE reservada reservada
LARGE reservada
LAST reservada reservada
LATERAL reservada
LEADING reservada reservada
LEFT reservada reservada
LENGTH não reservada não reservada
LESS reservada
LEVEL reservada reservada
LIKE reservada reservada
LIMIT reservada
LISTEN
LOAD
LOCAL reservada reservada
LOCALTIME reservada
LOCALTIMESTAMP reservada
LOCATION
LOCATOR reservada
LOCK
LOWER não reservada reservada
M não reservada
MAP reservada
MATCH reservada reservada
MAX não reservada reservada
MAXVALUE
MESSAGE_LENGTH não reservada não reservada
MESSAGE_OCTET_LENGTH não reservada não reservada
MESSAGE_TEXT não reservada não reservada
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
131
Apêndice I
Palavra-chave SQL 99 SQL 92
METHOD não reservada
MIN não reservada reservada
MINUTE reservada reservada
MINVALUE
MOD não reservada
MODE
MODIFIES reservada
MODIFY reservada
MODULE reservada reservada
MONTH reservada reservada
MORE não reservada não reservada
MOVE
MUMPS não reservada não reservada
NAME não reservada não reservada
NAMES reservada reservada
NATIONAL reservada reservada
NATURAL reservada reservada
NCHAR reservada reservada
NCLOB reservada
NEW reservada
NEXT reservada reservada
NO reservada reservada
NOCREATEDB
NOCREATEUSER
NONE reservada
NOT reservada reservada
NOTHING
NOTIFY
NOTNULL
NULL reservada reservada
NULLABLE não reservada não reservada
NULLIF não reservada reservada
NUMBER não reservada não reservada
NUMERIC reservada reservada
OBJECT reservada
OCTET_LENGTH não reservada reservada
OF reservada reservada
OFF reservada
OFFSET
OIDS
OLD reservada
ON reservada reservada
ONLY reservada reservada
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
132
Apêndice I
Palavra-chave SQL 99 SQL 92
OPEN reservada reservada
OPERATION reservada
OPERATOR
OPTION reservada reservada
OPTIONS não reservada
OR reservada reservada
ORDER reservada reservada
ORDINALITY reservada
OUT reservada
OUTER reservada reservada
OUTPUT reservada reservada
OVERLAPS não reservada reservada
OVERLAY não reservada
OVERRIDING não reservada
OWNER
PAD reservada reservada
PARAMETER reservada
PARAMETERS reservada
PARAMETER_MODE não reservada
PARAMETER_NAME não reservada
PARAMETER_ORDINAL_POSITION não reservada
PARAMETER_SPECIFIC_CATALOG não reservada
PARAMETER_SPECIFIC_NAME não reservada
PARAMETER_SPECIFIC_SCHEMA não reservada
PARTIAL reservada reservada
PASCAL não reservada não reservada
PASSWORD
PATH reservada
PENDANT
PLACING
PLI não reservada não reservada
POSITION não reservada reservada
POSTFIX reservada
PRECISION reservada reservada
PREFIX reservada
PREORDER reservada
PREPARE reservada reservada
PRESERVE reservada reservada
PRIMARY reservada reservada
PRIOR reservada reservada
PRIVILEGES reservada reservada
PROCEDURAL
PROCEDURE reservada reservada
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
133
Apêndice I
Palavra-chave SQL 99 SQL 92
PUBLIC reservada reservada
READ reservada reservada
READS reservada
REAL reservada reservada
RECHECK
RECURSIVE reservada
REF reservada
REFERENCES reservada reservada
REFERENCING reservada
REINDEX
RELATIVE reservada reservada
RENAME
REPEATABLE não reservada não reservada
REPLACE
RESET
RESTART
RESTRICT reservada reservada
RESULT reservada
RETURN reservada
RETURNED_LENGTH não reservada não reservada
RETURNED_OCTET_LENGTH não reservada não reservada
RETURNED_SQLSTATE não reservada não reservada
RETURNS reservada
REVOKE reservada reservada
RIGHT reservada reservada
ROLE reservada
ROLLBACK reservada reservada
ROLLUP reservada
ROUTINE reservada
ROUTINE_CATALOG não reservada
ROUTINE_NAME não reservada
ROUTINE_SCHEMA não reservada
ROW reservada
ROWS reservada reservada
ROW_COUNT não reservada não reservada
RULE
SAVEPOINT reservada
SCALE não reservada não reservada
SCHEMA reservada reservada
SCHEMA_NAME não reservada não reservada
SCOPE reservada
SCROLL reservada reservada
SEARCH reservada
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
134
Apêndice I
Palavra-chave SQL 99 SQL 92
SECOND reservada reservada
SECTION reservada reservada
SECURITY não reservada
SELECT reservada reservada
SELF não reservada
SENSITIVE não reservada
SEQUENCE reservada
SERIALIZABLE não reservada não reservada
SERVER_NAME não reservada não reservada
SESSION reservada reservada
SESSION_USER reservada reservada
SET reservada reservada
SETOF
SETS reservada
SHARE
SHOW
SIMILAR não reservada
SIMPLE não reservada
SIZE reservada reservada
SMALLINT reservada reservada
SOME reservada reservada
SOURCE não reservada
SPACE reservada reservada
SPECIFIC reservada
SPECIFICTYPE reservada
SPECIFIC_NAME não reservada
SQL reservada reservada
SQLCODE reservada
SQLERROR reservada
SQLEXCEPTION reservada
SQLSTATE reservada reservada
SQLWARNING reservada
STABLE
START reservada
STATE reservada
STATEMENT reservada
STATIC reservada
STATISTICS
STDIN
STDOUT
STORAGE
STRICT
STRUCTURE reservada
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
135
Apêndice I
Palavra-chave SQL 99 SQL 92
STYLE não reservada
SUBCLASS_ORIGIN não reservada não reservada
SUBLIST não reservada
SUBSTRING não reservada reservada
SUM não reservada reservada
SYMMETRIC não reservada
SYSID
SYSTEM não reservada
SYSTEM_USER reservada reservada
TABLE reservada reservada
TABLE_NAME não reservada não reservada
TEMP
TEMPLATE
TEMPORARY reservada reservada
TERMINATE reservada
THAN reservada
THEN reservada reservada
TIME reservada reservada
TIMESTAMP reservada reservada
TIMEZONE_HOUR reservada reservada
TIMEZONE_MINUTE reservada reservada
TO reservada reservada
TOAST
TRAILING reservada reservada
TRANSACTION reservada reservada
TRANSACTIONS_COMMITTED não reservada
TRANSACTIONS_ROLLED_BACK não reservada
TRANSACTION_ACTIVE não reservada
TRANSFORM não reservada
TRANSFORMS não reservada
TRANSLATE não reservada reservada
TRANSLATION reservada reservada
TREAT reservada
TRIGGER reservada
TRIGGER_CATALOG não reservada
TRIGGER_NAME não reservada
TRIGGER_SCHEMA não reservada
TRIM não reservada reservada
TRUE reservada reservada
TRUNCATE
TRUSTED
TYPE não reservada não reservada
UNCOMMITTED não reservada não reservada
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
136
Apêndice I
Palavra-chave SQL 99 SQL 92
UNDER reservada
UNENCRYPTED
UNION reservada reservada
UNIQUE reservada reservada
UNKNOWN reservada reservada
UNLISTEN
UNNAMED não reservada não reservada
UNNEST reservada
UNTIL
UPDATE reservada reservada
UPPER não reservada reservada
USAGE reservada reservada
USER reservada reservada
USER_DEFINED_TYPE_CATALOG não reservada
USER_DEFINED_TYPE_NAME não reservada
USER_DEFINED_TYPE_SCHEMA não reservada
USING reservada reservada
VACUUM
VALID
VALIDATOR
VALUE reservada reservada
VALUES reservada reservada
VARCHAR reservada reservada
VARIABLE reservada
VARYING reservada reservada
VERBOSE
VERSION
VIEW reservada reservada
VOLATILE
WHEN reservada reservada
WHENEVER reservada reservada
WHERE reservada reservada
WITH reservada reservada
WITHOUT reservada
WORK reservada reservada
WRITE reservada reservada
YEAR reservada reservada
ZONE reservada reservada
Tabela I.1 – Palavras-chave dos padrões SQL92 e SQL99.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
137
Apêndice II
Apêndice II – Expressões de valor
As expressões de valor são utilizadas em diversos contextos, como na lista de seleção do comando SELECT, como
novos valores das colunas nos comandos INSERT e UPDATE, e na condição de procura em vários comandos. Algumas
vezes, o resultado de uma expressão de valor é chamado de escalar, para distingui-lo do resultado de uma expressão de
tabela (que é uma tabela). As expressões de valor são, portanto, chamadas também de expressões escalares (ou mesmo
simplesmente de expressões). A sintaxe da expressão permite o cálculo de valores a partir de partes primitivas utilizando
operações aritméticas, lógicas, de conjunto e outras.
A expressão de valor pode se apresentar como uma das seguintes.
• Um valor constante ou literal.
• Uma referência à coluna.
• Uma referência ao parâmetro posicional, no corpo da definição de função ou de comando preparado.
• Uma expressão de índice.
• Uma expressão de seleção de campo.
• Uma chamada de operador.
• Uma chamada de função.
• Uma expressão de agregação.
• Uma conversão de tipo.
• Uma subconsulta escalar.
• Um construtor de matriz.
Existe outra expressão de valor entre parênteses, útil para agrupar sub-expressões e mudar precedências. Em acréscimo
a essa lista, existem diversas construções que podem ser classificadas como uma expressão, mas que não seguem
qualquer regra geral de sintaxe. Possuem, normalmente, a semântica de uma função ou de um operador. Um exemplo
é a cláusula IS NULL.
1. Referências à coluna
Uma coluna pode ser referenciada usando a forma correlação.nome_da_coluna, onde correlação é o nome de uma tabela,
possivelmente qualificado pelo nome do esquema, ou definido por meio da cláusula FROM, ou uma das palavras-chave
NEW ou OLD (NEW e OLD somente podem aparecer nas regras de reescrita, enquanto os outros nomes de correlação
podem ser usados em qualquer declaração SQL). O nome da correlação e o ponto separador podem ser omitidos se o
nome da coluna for único entre todas as tabelas utilizadas no comando corrente.
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
138
Apêndice II
2. Parâmetros posicionais
É utilizada uma referência a um parâmetro posicional para indicar um valor fornecido externamente a uma declaração
SQL. Os parâmetros são utilizados na definição de funções SQL e de comandos preparados. Algumas bibliotecas cliente
também suportam a especificação de valores de dados, separado da cadeia de caracteres do comando SQL e, nesses
casos, os parâmetros são utilizados para fazer referência a valores de dados fora de linha. A forma de fazer referência
a um parâmetro é: $número
Por exemplo, considere a definição da função dept como sendo:
CREATE FUNCTION dept(text) RETURNS dept AS ‘SELECT * FROM dept WHERE nome = $1’ LANGUAGE SQL;
Nesse caso, $1 será substituído pelo primeiro argumento da função quando essa for chamada.
3. Índices
Se uma expressão produzir um valor do tipo matriz, então um elemento específico do valor matricial pode ser extraído
escrevendo:
expressão [índice]
e vários elementos adjacentes podem ser extraídos escrevendo:
expressão [índice_inferior:índice_superior].
Nesse caso, os colchetes [ ] devem aparecer literalmente. Cada índice é por si só uma expressão, que deve produzir um
valor inteiro.
Geralmente, a expressão matricial deve estar entre parênteses, mas os parênteses podem ser omitidos quando a expressão
a ser indexada é apenas a referência a uma coluna ou a um parâmetro posicional. Podem ser concatenados vários índices
quando a matriz original for multidimensional. Por exemplo:
minha_tabela.matriz_coluna[4]
minha_tabela.matriz_duas_dim[17][34]
$1[10:42]
(funcao_matriz(a,b))[42]
4. Escolha de campo
Se uma expressão produzir um valor do tipo composto (tipo linha), então pode-se extrair um campo específico da linha
escrevendo:
expressão.nome_do_campo
Geralmente, a expressão de linha deve estar entre parênteses, mas os parênteses podem ser omitidos quando a expressão
de seleção for apenas uma referência a tabela ou a um parâmetro posicional. Por exemplo,
minha_tabela.minha_coluna
$1.alguma_coluna
(funcao_de_linha(a,b)).col3
Portanto, uma referência à coluna qualificada é, na verdade, apenas um caso especial da sintaxe de seleção de campo.
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
139
Apêndice II
5. Chamadas de operador
Existem três sintaxes possíveis para chamada de operador:
• expressão operador expressão (operador binário-intermediário);
• operador expressão (operador unário-esquerdo);
• expressão operador (operador unário-direito).
onde o termo operador segue as regras de sintaxe ou é uma das palavras-chave AND, OR ou NOT, ou é um nome de
operador qualificado na forma:
OPERATOR(esquema.nome_do_operador)
Quais são os operadores existentes, e se são unários ou binários, depende de quais operadores foram definidos pelo
sistema e pelo usuário.
6. Chamadas de função
A sintaxe para chamada de função é o nome da função (possivelmente qualificado pelo nome do esquema), seguido por
sua lista de argumentos entre parênteses:
função ([expressão [, expressão ... ]] )
Por exemplo, a função abaixo calcula a raiz quadrada de 2:
sqrt(2)
7. Funções de agregação
Uma expressão de agregação representa a aplicação de uma função de agregação nas linhas selecionadas pela consulta.
Uma função de agregação reduz vários valores de entrada a um único valor de saída, tal como a soma ou a média dos
valores entrados. A sintaxe da expressão de agregação é uma das seguintes:
• nome_da_agregação (expressão);
• nome_da_agregação (ALL expressão);
• nome_da_agregação (DISTINCT expressão);
• nome_da_agregação ( * ).
onde nome_da_agregação é uma agregação definida anteriormente (possivelmente qualificado pelo nome do esquema),
e expressão é qualquer expressão de valor que não contenha uma expressão de agregação.
A primeira forma de expressão de agregação chama a função de agregação para todas as linhas de entrada onde a
expressão fornecida produz um valor não nulo (na verdade, é decisão da função de agregação ignorar ou não os valores
nulos — porém, todas as funções-padrão o fazem). A segunda forma é idêntica à primeira, porque ALL é o padrão. A
terceira forma chama a função de agregação para todos os valores distintos não nulos da expressão, encontrados nas
linhas de entrada. A última forma chama a função de agregação uma vez para cada linha de entrada, independentemente
do valor ser nulo ou não; como nenhum valor específico de entrada é especificado, geralmente é útil apenas para a função
de agregação count().
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
140
Apêndice II
Por exemplo, count(*) retorna o número total de linhas de entrada; count(f1) retorna o número de linhas de entrada, onde
f1 não é nulo; count(distinct f1) retorna o número de valores distintos não nulos de f1.
Uma expressão de agregação pode aparecer apenas na lista de resultados ou na cláusula HAVING do comando SELECT.
Seu uso é proibido nas outras cláusulas, tal como WHERE, porque essas cláusulas são avaliadas logicamente antes dos
resultados das agregações estarem formados.
Quando uma expressão de agregação aparece em uma subconsulta, normalmente a agregação é avaliada a partir das
linhas da subconsulta. Porém ocorre uma exceção quando o argumento da agregação contém apenas variáveis do nível
externo: a agregação então pertence ao nível externo mais próximo, sendo avaliada a partir das linhas dessa consulta.
A expressão de agregação como um todo é, então, uma referência externa para a subconsulta onde aparece, agindo
como uma constante em qualquer avaliação da subconsulta. A restrição de aparecer apenas na lista de resultados ou na
cláusula HAVING se aplica com respeito ao nível da consulta que a agregação pertence.
8. Conversões de tipo
Uma conversão de tipo (type cast) especifica a conversão de um tipo de dado em outro. O PostgreSQL aceita duas
sintaxes equivalentes para conversão de tipo:
CAST ( expressão AS tipo )
expressão::tipo
Quando a conversão é aplicada a uma expressão de valor de tipo conhecido, representa uma conversão em tempo de
execução. A conversão será bem sucedida apenas se estiver disponível uma operação de conversão de tipo adequada.
Deve ser observado que isso é sutilmente diferente da utilização de conversão com constantes. Uma conversão aplicada a
uma literal cadeia de caracteres sem adornos representa a atribuição inicial do tipo ao valor constante literal e, portanto,
será bem-sucedida para qualquer tipo (se o conteúdo do literal cadeia de caracteres possuir uma sintaxe válida para
servir de entrada para o tipo de dado).
Geralmente a conversão explícita de tipo pode ser omitida quando não há ambigüidade em relação ao tipo que a expressão
de valor deve produzir (por exemplo, quando é atribuída a uma coluna de tabela); o sistema aplica automaticamente a
conversão de tipo nesses casos. Entretanto, a conversão automática de tipo é feita apenas para as conversões marcadas
nos catálogos do sistema como “OK para aplicar implicitamente”. As outras conversões devem ser chamadas por meio
da sintaxe de conversão explícita. Essa restrição tem por finalidade impedir que aconteçam conversões surpreendentes
aplicadas em silêncio.
Também é possível especificar uma conversão de tipo utilizando a sintaxe na forma de função:
nome_do_tipo ( expressão )
Entretanto, somente funciona para os tipos cujos nomes também são válidos como nome de função. Por exemplo, double
precision não pode ser utilizado dessa maneira, mas a forma equivalente float8 pode. Também, os nomes interval, time e
timestamp somente podem ser utilizados dessa maneira se estiverem entre aspas, devido a conflitos sintáticos. Portanto, o
uso da sintaxe de conversão na forma de função pode ocasionar inconsistências, devendo ser evitada em novas aplicações.
9. Subconsultas escalares
Uma subconsulta escalar é um comando SELECT comum, entre parênteses, que retorna exatamente uma linha com uma
coluna. O comando SELECT é executado e o único valor retornado é utilizado na expressão de valor envoltória. É errado
utilizar uma consulta que retorne mais de uma linha ou mais de uma coluna como subconsulta escalar, porém, se durante
uma determinada execução a subconsulta não retornar nenhuma linha, não acontece nenhum erro: o resultado escalar
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
141
Apêndice II
é assumido como nulo. A subconsulta pode fazer referência a variáveis da consulta envoltória, as quais atuam como
constantes durante a avaliação da subconsulta.
Por exemplo, a consulta abaixo retorna a maior população de cidade de cada estado:
SELECT nome, (SELECT max(populacao) FROM cidades WHERE cidades.estado = estados.nome) FROM estados;
10. Construtores de matriz
Um construtor de matriz é uma expressão que constrói um valor matriz a partir dos valores de seus elementos membros.
Um construtor de matriz simples é composto pela palavra-chave ARRAY, um abre colchetes [, uma ou mais expressões
(separadas por vírgula) para os valores dos elementos da matriz e, finalmente, um fecha colchetes ]. Por exemplo,
SELECT ARRAY[1,2,3+4];
array
---------
{1,2,7}
(1 linha)
O tipo de dado do elemento da matriz é o tipo comum das expressões membro, determinado pela utilização das mesmas
regras das construções UNION e CASE.
Os valores matriz multidimensional podem ser construídos aninhando construtores de matriz. Nos construtores internos,
a palavra chave ARRAY pode ser omitida. Por exemplo, esses dois comandos produzem o mesmo resultado:
SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]];
array
---------------
{{1,2},{3,4}}
(1 linha)
SELECT ARRAY[[1,2],[3,4]];
array
---------------
{{1,2},{3,4}}
(1 linha)
Uma vez que as matrizes multidimensionais devem ser retangulares, os construtores internos no mesmo nível devem
produzir submatrizes com dimensões idênticas. Os elementos construtores de matriz multidimensional podem ser qualquer
coisa que produza uma matriz do tipo apropriado, e não apenas uma construção sub-ARRAY. Por exemplo:
CREATE TABLE arr(f1 int[], f2 int[]);
INSERT INTO arr VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]);
SELECT ARRAY[f1, f2, ‘{{9,10},{11,12}}’::int[]] FROM arr;
array
------------------------------------------------
{{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}
(1 linha)
Também é possível construir uma matriz a partir do resultado de uma subconsulta. Nessa forma, o construtor de matriz é
escrito com a palavra chave ARRAY seguida por uma subconsulta entre parênteses, e não entre colchetes. Por exemplo:
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
142
Apêndice II
SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE ‘bytea%’);
?column?
-------------------------------------------------------------
{2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31}
(1 linha)
A subconsulta deve retornar uma única coluna. A matriz unidimensional produzida terá um elemento para cada linha no
resultado da subconsulta, com o tipo do elemento correspondendo ao da coluna de saída da subconsulta.
11. Regras para avaliação de expressão
A ordem de avaliação das subexpressões não é definida. Em particular, as entradas de um operador ou função não são
necessariamente avaliadas da esquerda para a direita, ou em qualquer outra ordem fixada.
Além disso, se o resultado da expressão puder ser determinado avaliando apenas algumas de suas partes, então as outras
subexpressões podem nem ser avaliadas. Por exemplo, se for escrito
SELECT true OR alguma_funcao();
então alguma_funcao() não será (provavelmente) chamada. Esse é o mesmo caso de quando é escrito
SELECT alguma_funcao() OR true;
Deve ser observado que isso não é o mesmo que os “curtos circuitos” esquerda para direita de operadores booleanos
encontrados em algumas linguagens de programação.
Como conseqüência, não é bom utilizar funções com efeitos colaterais como parte de expressões complexas. É
particularmente perigoso confiar em efeitos colaterais, ou na ordem de avaliação nas cláusulas WHERE e HAVING, porque
essas cláusulas são reprocessadas inúmeras vezes como parte do desenvolvimento do plano de execução. As expressões
booleanas (combinações de AND/OR/NOT) nessas cláusulas podem ser reorganizadas em qualquer forma permitida pelas
leis da álgebra booleana.
Quando for essencial obrigar a ordem de avaliação, pode ser utilizada uma construção CASE. Por exemplo, essa é uma
forma não confiável para tentar evitar uma divisão por zero na cláusula WHERE:
SELECT ... WHERE x <> 0 AND y/x > 1.5;
Mas esta forma é segura:
SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;
A construção CASE utilizada dessa forma impede as tentativas de otimização devendo, portanto, ser utilizada
apenas quando for necessário (Nesse exemplo em particular, sem dúvida seria melhor evitar o problema escrevendo
y > 1.5*x).
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
143
Apêndice III
Apêndice III – Comandos SQL
Esta parte contém informação de referência para os comandos SQL.
ABORT – interrompe a transação corrente
ALTER AGGREGATE – altera a definição de uma função de agregação
ALTER CONVERSION – altera a definição de uma conversão de codificação
ALTER DATABASE – altera um banco de dados
ALTER DOMAIN – altera a definição de um domínio
ALTER FUNCTION – altera a definição de uma função
ALTER GROUP – altera um grupo de usuários
ALTER LANGUAGE – altera a definição de uma linguagem procedural
ALTER OPERATOR CLASS – altera a definição de uma classe de operadores
ALTER SCHEMA – altera a definição de um esquema
ALTER SEQUENCE – altera a definição de um gerador de sequência
ALTER TABLE – altera a definição de uma tabela
ALTER TRIGGER – altera a definição de um gatilho
ALTER USER – altera uma conta de usuário do banco de dados
ANALYZE – coleta estatísticas do banco de dados
BEGIN – inicia um bloco de transação
CHECKPOINT – força um ponto de controle no registro de transação
CLOSE – fecha o cursor
CLUSTER – agrupa a tabela de acordo com um índice
COMMENT – define ou muda o comentário sobre um objeto
COMMIT – efetiva a transação corrente
COPY – copia dados entre um arquivo e uma tabela
CREATE AGGREGATE – cria uma função de agregação
CREATE CAST – cria uma conversão de tipo de dado
CREATE CONSTRAINT TRIGGER – cria um gatilho de restrição
CREATE CONVERSION – cria uma conversão de codificação
CREATE DATABASE – cria um banco de dados
CREATE DOMAIN – cria um domínio
CREATE FUNCTION – cria uma função
CREATE GROUP – cria um grupo de usuários
CREATE INDEX – cria um índice
S
i
s
t
e
m
a
s

d
e

B
a
n
c
o

d
e

D
a
d
o
s
144
Apêndice III
CREATE LANGUAGE – cria uma linguagem procedural
CREATE OPERATOR – cria um operador
CREATE OPERATOR CLASS – cria uma classe de operadores
CREATE RULE – cria uma regra de reescrita
CREATE SCHEMA – cria um esquema
CREATE SEQUENCE – cria um gerador de sequência
CREATE TABLE – cria uma tabela
CREATE TABLE AS – cria uma tabela a partir dos resultados de uma consulta
CREATE TRIGGER – cria um gatilho
CREATE TYPE – cria um tipo de dado
CREATE USER – cria uma conta de usuário do banco de dados
CREATE VIEW – cria uma visão
DEALLOCATE – remove um comando preparado
DECLARE – define um cursor
DELETE – exclui linhas de uma tabela
DROP AGGREGATE – remove uma função de agregação
DROP CAST – remove uma conversão de tipo de dado
DROP CONVERSION – remove uma conversão de codificação
DROP DATABASE – remove um banco de dados
DROP DOMAIN – remove um domínio
DROP FUNCTION – remove uma função
DROP GROUP – remove um grupo de usuários
DROP INDEX – remove um índice
DROP LANGUAGE – remove uma linguagem procedural
DROP OPERATOR – remove um operador
DROP OPERATOR CLASS – remove uma classe de operadores
DROP RULE – remove uma regra de reescrita
DROP SCHEMA – remove um esquema
DROP SEQUENCE – remove uma sequência
DROP TABLE – remove uma tabela
DROP TRIGGER – remove um gatilho
DROP TYPE – remove um tipo de dado
DROP USER – remove uma conta de usuário do banco de dados
DROP VIEW – remove uma visão
END – efetiva a transação corrente
EXECUTE – executa um comando preparado
P
ó
s
-
G
r
a
d
u
a
ç
ã
o

a

D
i
s
t
â
n
c
i
a
145
Apêndice III
EXPLAIN – mostra o plano de execução de um comando
FETCH – traz linhas de uma consulta usando um cursor
GRANT – define privilégios de acesso
INSERT – cria novas linhas na tabela
LISTEN – ouve uma notificação
LOAD – carrega ou recarrega um arquivo de biblioteca compartilhada
LOCK – bloqueia uma tabela
MOVE – posiciona o cursor
NOTIFY – gera uma notificação
PREPARE – prepara um comando para execução
REINDEX – reconstrói índices
RESET – redefine o valor de um parâmetro em tempo de execução com seu valor padrão
REVOKE – revoga privilégios de acesso
ROLLBACK – interrompe a transação corrente
SELECT – retorna linhas de uma tabela ou de uma visão
SELECT INTO – cria uma tabela a partir dos resultados de uma consulta
SET – muda um parâmetro de tempo de execução
SET CONSTRAINTS – define os modos de verificação da restrição na transação corrente
SET SESSION AUTHORIZATION – define o identificador do usuário da sessão e o identificador do usuário corrente, da
sessão corrente.
SET TRANSACTION – define as características da transação corrente
SHOW – mostra o valor de um parâmetro de tempo de execução
START TRANSACTION – inicia um bloco de transação
TRUNCATE – esvazia a tabela
UNLISTEN – para de escutar uma notificação
UPDATE – atualiza linhas de uma tabela
VACUUM – limpa e opcionalmente analisa um banco de dados