Escolar Documentos
Profissional Documentos
Cultura Documentos
Resumo SBD
Resumo SBD
4 – SQL
As linguagens formais proporcionam uma notação concisa para a representação de
consultas, mas os bancos de dados comerciais precisam de uma linguagem de
consulta mais fácil para o utilizador – a SQL – combinação de construtores em álgebra
e cálculo relacional.
Ela é mais que simples linguagem de consulta pois permite também definir estruturas
de dados, modificar dados e especificação de restrições de segurança.
4.1. Histórico
SQL=Structured Query Language – Linguagem de Consulta Estruturada. Actual SQL-
92.
A linguagem SQL tem diversas partes:
Linguagem de definição de dados – DDL
Linguagem interactiva de manipulação de dados –DML: baseada na álgebra relacional
e no cálculo relacional de tuplos.
Incorporação DML
Definição de visões
Autorização
Integridade
Controle de transacções
Neste capítulo cobre-se a DML interactiva e os recursos DML básicos da SQL.
Usaremos como exemplo empresa com os seguintes esquemas de relações:
Esquema_agência=(nome_agência, cidade_agência, fundos)
Esquema_cliente=(nome_cliente, rua_cliente, cidade_cliente)
Esquema_empréstimo=(nome_agência, número_empréstimo, total)
Esquema_devedor=(nome_cliente, número_empréstimo)
Esquema_conta=(nome_agência, número_conta, saldo)
Esquema_depositante=(nome_cliente, número_conta)
4.2.8. Duplicidade
O uso de relações com duplicidade (tuplos repetidos) é por vezes útil. A SQL dá
também o número de repetições.
Podemos definir a semântica da duplicidade de uma consulta SQL usando versões
multiconjuntos dos operadores relacionais.
... será preciso???
4.8. Visões
será preciso???
4.9.1. Remoção
Um pedido de remoção de dados é expresso muitas vezes do mesmo modo que uma
consulta.
Podemos remover apenas tuplos inteiros.
delete from r
where P
ex: delete from depositante
where nome_cliente = “Smith”
ex: delete from conta
where nome_agência in (select nome_agência
from agência
where cidade_agência = “Perryridge”)
Assim, podemos ver que podemos atingir mais que uma relação numa operação de
delete, por meio de comandos select-from-where aninhados numa cláususla where de
um delete.
Os tuplos a remover também podem ser da relação da cláusula delete:
ex: delete from conta
where saldo < (select avg (saldo)
from conta)
É importante que todos ostestes sejam efectuados antes de remover.
4.9.2. Inserção
Para inserir dados numa relação podemos especificar um tuplo a ser inserido ou
escrever uma consulta cujo resultado é um conjunto de tuplos a inserir.
ex: + simples: insert into conta
values (“Perryridge”, A-9732”, 1200)
Para quem não se lembrar da ordem:
insert into conta (nome_agência, número_conta, saldo)
values (“Perryridge”, A-9732”, 1200)
ou qualquer outra ordem.
+ genericamente: insert into conta
select nome_agência, número_empréstimo, 200
from empréstimo
where nome_agência = “Perryridge”
mal: insert into conta
select *
from conta
Pode inserir-se tuplos com atributos a null, mas, com DDL pode impedir-se isso se
assim o pretendermos.
4.9.3. Actualizações
ex: update conta
set saldo = saldo * 1.05
ex: update conta
set saldo = saldo * 1.06
where saldo > 10000
update conta
set saldo = saldo*1.05
where saldp <= 10000
atenção à ordem, portanto.
4.10.1. Exemplos
empréstimo inner join devedor on empréstimo.número_empréstimo =
devedor.número_empréstimo
Os atributos do resultado consistem nos atributos da relação da esquerda seguidos
dos atributos da relação da direita (com repetição).
podemos rebaptizar a relação resultado, bem assim como os atributos resultado, com
a cláusula as.
O left outer join é processado como se segue: Primeiro, o resultado da junção interna
(inner join) é processado como anteriormente. Então, para todo o tuplo t da relação
empréstimo do lado esquerdo que não apresente correspondência com nenhum tuplo
da relação devedor do lado direito da junção interna, um tuplo r é adicionado ao
resultado da junção da maneira como será descrita. Os atributos do tuplo r que são
derivados da relação do lado esquerdo são preenchidos pelos valores do tuplo t e os
restantes são preenchidos com o valor nulo.
ex: “Encontre todos os clientes que tenham uma conta, mas nenhum empréstimo no
banco”
select d-CN
from (depositante left outer join devedor
on depositante.nome_cliente = devedor.nome_cliente)
as db1 (d-CN, número_conta, b-CN, número_empréstimo)
where b-CN is null
6.3. Asserções
Uma asserção é um predicado que expressa uma condição que desejamos que seja
sempre satisfeita no banco de dados. Restrições de domínio e regras de integridade
são formas especiais de asserções. Outros ex:
A soma de todos os totais em conta empréstimo de cada uma das agências deve ser
menor que a soma de todos os saldos das contas dessa agência.
Todo o empréstimo deve ter ao menos um cliente que mantenha uma conta com saldo
mínimo de 1000 dólares.
α --> β é trivial se β ⊆ α
Para distinguir os conceitos de uma relação que satisfaz uma dependência e de uma
dependência realizando-se num esquema, voltemos ao ex. do banco.
Se considerarmos a relação cliente (com o Esquema_cliente), como mostrado,
notamos que rua_cliente -> cidade_cliente é satisfeita. Mas, no mundo real, é possível
que duas cidades distintas tenham o mesmo nome de rua. Logo, não incluiremos a
dependência no conjunto de dependências funcionais que são realizadas no
Esquema_cliente.
Na relação empréstimo (do Esquema_empréstimo) vemos que número_empréstimo-
>total é satisfeita. Aqui é diferente, pois na vida real é normal que cada conta tenha
apenas um total. Portanto queremos que a condição número_empréstimo -> toatla
seja sempre satisfeita para a relação empréstimo. Por outras palavras, precisamos da
restrição número_empréstimo -> total para o Esquem_empréstimo.
Já na relação agência, nome_agência -> fundos é realaizada no Esquema_agência, já
o mesmo não se passando com o inverso, embora na relação, essa dependência
possa ser satisfeita.
exercício:
Computar a cobertura canónica para F, sendo F, no esquema (A,B,C)
A --> BC
B --> C
A --> B
AB --> C
Solução: A --> B
B --> C
EXERCÍCIOS:
6.7. Por que há certas dependências funcionais chamadas de triviais?
Porque são dependências funcionais satisfeitas por todas as relações. Em geral, uma
dependência funcional α --> β é trivial se β ⊆ α
6.8. Relacione todas as dependências atendidas (satisfeitas na) pela relação da figura:
A B C
a1 b1 c1
a1 b1 c2
a2 b1 c1
a2 b1 c3
A --> B
AC --> B
+ as triviais : A --> A B --> B C --> C AB --> A, etc.
6.9. Use a definição de dependência funcional para discutir como funciona cada um
dos axiomas da Armstrong (reflexividade, aumento e transitividade)
Reflexividade:
se t1[α] = t2[α] e β ⊆ α então forçosamente α=βγ. Logo t1[β] = t2 [β]
Incremento:
se t1[α] = t2[α] , de α --> β temos que t1[β] = t2[β]. Como, por reflexividade γ --> γ ,
se t1[γ] = t2[γ] então t1[γα] = t2[γβ]
Transitividade: Está feito na página 204 do livro.
6.10. Explique como a dependência funcional pode ser usada par explicar o seguinte:
Um conjunto de relacionamentos um para um entre o conjunto de entidades
estudantes e orientador.
Um conjunto de relacionamentos muitos para um entre o conjunto de entidades
estudantes e orientador.
e o B?
também não.
ver se C ou D são extrínsecos em CD-->E
(F – {CD->E}) U {(CD – D) -->E}
A-->BC U C-->E
B-->D
E-->A
CD-->E
A-->B
A-->C
A-->D
A-->E
CD-->A
BC-->E
BC-->A
Então a cobertura canónica será mesmo o conjunto das dependências dadas. Não é
possível reduzir.
CAP. 13 – TRANSACÇÕES
Consistência:
A exigência de consistência significa que que a soma de A com B deve permanecer
inalterada após a execução da transacção.
É responsabilidade do programador da aplicação que codifica a transacção. Esta
tarefa pode ser facilitada por meio do teste automático dos requisitos de integridade,
conforme visto no cap. 6.
Atomicidade:
Suponhamos que há uma falha a meio, depois de write(A) mas antes de write(B) da
transacção (falta de energia, falha da máquina ou de software). Então a soma de A+B
não é preservada --> estado inconsistente.
A ideia básica por detrás da atomicidade é a seguinte: O sistema de banco de dados
mantém um registo (em disco) dos antigos valores de quaisquer dados sobre os quais
a transacção executa uma gravação e, se a transacção não for completada, os valores
antigos são restabelecidos para parecer que nada dela foi executado.
É da responsabilidade do próprio sistema de banco de dados.
Durabilidade:
Garante que uma vez completada a transacção com sucesso, todas as actualizações
realizadas permanecerão mesmo que depois haja uma falha no sistema.
Suponhamos agora que uma falha se dá e há perda de dados na memória, mas não
no disco. Podemos garantir a durabilidade se se garantir uma de:
1. As actualizações realizadas pela transacção foram gravadas em disco, antes da
transacção se completar
2. Informações gravadas no disco, sobre as actualizações realizadas pela transacção,
são suficientes para que o banco de dados possa reconstruir essas actualizações
quando o sitema for reiniciado após uma falha.
É da responsabilidade do componente de gerenciamento de recuperação.
Isolamento:
Quando há mais que uma transacção em simultâneo (concorrentes) com operações
que podem ser intercaladas.
Uma solução é realizar transacções em série mas isso é muito ineficiente. Há pois
outras técnicas que veremos à frente.
É da responsabilidade do componente de controlo de concorrência.
13.5. SERIALIZAÇÃO
Vamos só considerar as operações significativas do ponto de vista da escala de
execução: read e write.
Dizemos que S tem visão serializada se for equivalente em visão a uma escala de
execução sequencial.
13.6. RECUPERAÇÃO
Se uma Ti falha, precisamos de desfazer os seus efeitos, mas também é necessa´rio
assegurar que qualquer transacção Tj que dependa de Ti seja abortada.
Para assegurar isso temos de colocar restrições aos tipos de escalas que se podem
usar.
13.6.2.
ESCALAS EM CASCATA
O retorno em cascata é indesejável, mesmo em escalas recuperáveis, já que leva a
destruir uma quantidade de trabalho. Logo, é conveniente restringir às sem cascata.
Uma escala sem cascata é aquela na qual para cada par de transacções Ti e Tj, tal
que Tj leia um item de dados previamente escrito por Ti, a operação de efectivação de
Ti apareça antes da operação de leitura de Tj. Toda a escala sem cascata é
recuperável.
EXERCÍCIOS
13.1.Liste as propriedades ACID. Explique a utilidade de cada uma.
Atomicidade: Para garantir que uma transacção (com várias operações) ou é
totalmente feita ou nada é feito. Se assim não fosse corríamos facilmente o risco de
inconsistência de dados. Da responsabilidade do programador.
Consistência: Para garantir que nada “desaparece” ou “aparece” sempre que é feita
qualquer transacção. É da responsabilidade do sistema de base de dados.
Isolamento: Apesar de duas transacções poderem ser executadas em simultâneo,
para rendibilizar os recursos de sistema, para cada uma delas é como se a outra não
existisse. É da responsabilidade do sistema de controlo de concorrência
Durabilidade: Depois de efectivada a transacção há que garantir que os dados se
mantêm, mesmo que haja qualquer falha de sistema. Da responsabilidade do sistema
de recuperação.
13.2. Suponha que haja um sistema de banco de dados que nuca falhe. Um
gerenciador de recuperação é necessário para esse sistema?
Não, uma vez que este é responsável pela recuperação de dados consistentes quando
há uma falha a meio de uma transacção que tem de ser pois abortada, ou de uma
falha mesmo após a efectivação de uma transacção para garantir a durabilidade. Se
não há falhas, não se justifica este componente.
13.3. Considere o sistema de arquivo de seu sistema operativo favorito. Os aspectos
de atomicidade e durabilidade são relevantes em relação aos seguintes itens?
Justifique a sua resposta.
(a) Utilizador do sistema operativo
(b) Implementador do sistema de ficheiros.
(b) Sim. Por exemplo se o utilizador manda gravar um ficheiro para actualização,
espera-se que o sistema grave/actualize a versão antiga totalmente, ou, se impossível
por falha, que não faça nada, de modo a ter acessível a versão antiga. Por outro lado,
quanto à durabilidade também pois se se termina a operação (“efectivação”) que,
eventualmente, apaga versões anteriores, espera-se que essa versão se mantenha
“para sempre”.
(a) Não. O utilizador não tem que se preocupar com isso.
13.4. Os implementadores de sistemas de banco de dados prestaram muito mais
atenção às propriedades ACID que os implementadores de sistemas de arquivo. Por
quê?
Porque uma base de dados, se não atender aquelas propriedades, rapidamente deixa
de ser fiável e os dados tornam-se completamente inconsistentes. Além disso as
bases de dados jogam com grandes quantidades de informação interrelacionada e por
vezes sensível e, onde, inconsistências não são fáceis de descobrir.
No caso dos sistemas de ficheiros embora possa ser produzida informação
inconsistente, é muito mais fácil descobrir esse facto.
13.5. Durante a sua execução, uma transacção atravessa vários estados, até ser
finalmente efectivada ou abortada. Liste todas as possíveis sucessões de estados
pelos quais uma transacção pode passar. Explique por que cada transição de estado
pode acontecer.
Activa – estado inicial – em execução
parcialmente efectivada – depois de a última operação já ter sido feita mas ainda em
memória. Daqui pode ir para abortada ou efectivada
efectivada – Concluída, sem possibilidade de ser abortada
Em falha...
abortada – Chegou-se à conclusão que a transacção não pode ser terminada. Há que
recuperar os dados antigos e desfazer as operações da transacção já realizadas.
13.6. Explique a distinção entre os termos escala sequencial e escala serializável
Escala sequencial é quando as transacções se realizam uma a seguir à outra. Não há
concorrência. Escala serializável é uma escala em que embora isso não se verifique,
os resultados são equivalentes a uma escala sequencial.
13.7. Considere as duas transacções seguintes:
T1: read(A);
read(B);
if A = 0 then B:= B+1;
write(B)
T2: read(B);
read(A);
if B = 0 then A:=A+1;
write(A)
Seja um requisito de consistência A=0 V B=0, com valores iniciais A=B=0.
(a) Mostre que toda a execução sequencial que envolve essas duas transacções
preserva a consistência do banco de dados.
Se T1, T2, o resultado final é B=1 e A=0 pois o if de T2 é falso. Similarmente se T2,T1
o resultado final é A=1 e B=0, pelo que a consistência se preserva.
(b) Mostre uma execução concorrente de T1 e T2 que produza uma escala não
serializável
T1 T2
read(A)
read(B)
read(B)
read(A)
if B ...
write(A)
if A...
write(B)
T1 --------> T2
ex:
read(B)
read(A)
read(A)
if A ...
write(B)
read(B)
if B...
write(A)
13.8. Dado que toda a escala conflito serializável é visão serializável, por que
enfatizamos serialização de conflito em vez de serialização de visão?
Porque o algoritmo para testar a serialização de conflito é muito mais simples.
13.9.
Considere o gráfico de precedência da figura. A escala correspondente é conflito
serializável? Justifique.
É. O gráfico de precedência não tem ciclos.
13.10.