Examen Corrige SGBD nfp107 2014

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 12

ISAE – Beyrouth, Centre associé au CNAM-Paris

Systèmes de gestion de bases de données – NFP107–


Corrigé de l’examen final 2014

Abdallah EL Asmar

Exercice 1 : PL/SQL (8 pts)


Considérons le schéma relationnel suivant :
Présentateurs (noPres, nom, âge, sexe, nbEmissions)
Programmes (noProg, nom, heureDébut, durée,#noPresPrincipal)
Présente (#noProg, #noPres)
Emissions (noEm, #noProg, dateEmission, pourcentage_spectateurs)
Invités (noInv, prénom, nom, sexe)
Participe (#noEm, #noInv)

Q1. Définir un bloc PL/SQL nommé qui affiche pour chaque programme, les numéros des
invités qui ont participé à la dernière émission.

1ère solution:
Cette solution consiste à :
- Créer un curseur pour trouver les numéros et les noms de tous les programmes qui ont
des émissions,
- Trouver la dernière date d’émission d’un programme
- Créer un curseur paramétré qui prend en argument un numéro d’un programme et la
dernière date d’émission de ce programme.

Create or replace procedure Q1 is


cursor lesProgs is
select noProg, nom from Programmes
where noProg in (select noProg from Emissions);
cursor lesInvites (Num Programmes.noProg%type, Dernier date) is
select p.noInv
from Emissions e, Participe p
where e.noEm = p.noEm
and e.noProg = Num
and e.dateEmission = Dernier;
maxDate date;
Begin
For C1 in lesProgs loop
Select max (dateEmission) into maxDate
From Emissions
Where noProg = C1.noProg;
Dbms_output.put_line('Les no. des invites de la dernière émission
du programme : '|| C1.nom) ;
For C2 in lesInvites (C1.noProg, maxDate) loop
Dbms_output.put_line (C2.noInv) ;
End loop;
End loop;
End;
/

1/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

2ème solution:
La seule différence avec la 1ère solution est l’utilisation d’une requête imbriquée dans la
définition du deuxième curseur pour trouver la dernière date d’émission d’un programme.

Create or replace procedure Q1 is


cursor lesProgs is
select noProg, nom from Programmes
where noProg in (select noProg from Emissions);
cursor lesInvites (Num Programmes.noProg%type) is
select p.noInv
from Emissions e, Participe p
where e.noEm = p.noEm
and e.noProg = Num
and e.dateEmission = (Select max (dateEmission)
From Emissions
Where noProg = Num);
Begin
For C1 in lesProgs loop
Dbms_output.put_line('Les no. des invites de la dernière émission
du programme : '|| C1.nom) ;
For C2 in lesInvites (C1.noProg) loop
Dbms_output.put_line (C2.noInv) ;
End loop;
End loop;
End;
/

3ème solution:
Cette solution consiste à trouver les numéros et les noms de tous les programmes et à appeler
pour chaque programme une procédure permettant d’afficher les invités de la dernière
émission de ce programme.

Create or replace procedure Q1 is


cursor lesProgs is
select noProg, nom from Programmes
where noProg in (select noProg from Emissions);
Begin
For C1 in lesProgs loop
Dbms_output.put_line('Les no. des invites de la dernière émission
du programme : '|| C1.nom) ;
afficherInvites(C1.noProg);
End loop;
End;

Create or replace procedure afficherInvites (Num Programmes.noProg%type) is

2/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

cursor lesInvites is
select p.noInv
from Emissions e, Participe p
where e.noEm = p.noEm
and e.noProg = Num
and e.dateEmission = (Select max (dateEmission)
From Emissions
Where noProg = Num);
Begin
For C in lesInvites loop
Dbms_output.put_line (C.noInv) ;
End loop;
End;
/

4ème solution:
Cette solution consiste à créer une seule requête pour trouver le résultat.

Create or replace procedure Q1 is


cursor lesInvites is
select p.noProg, p.nom, a.noInv
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg
and e.noEm = a.noEm
and (e.noProg, e.dateEmission ) in
(select noProg, max(dateEmission)
from Emissions
group by noProg);
Begin
Dbms_output.put_line(' Nom du programme ----- Numéro invité ') ;
For C in lesInvites loop
Dbms_output.put_line(C.nom ||' '|| C.noInv) ;
End loop;
End;
/

Q2. Définir un bloc PL/SQL nommé qui affiche les numéros et les noms des présentateurs
principaux qui ont présenté un seul programme.

Solution:
La solution consiste à créer un curseur permettant de trouver le numéro et le nom de tout
présentateur si ce présentateur est le présentateur principal d’un seul programme. Pour
exprimer cette condition, on peut utiliser une requête imbriquée permettant de vérifier si le
nombre de programmes présentés par un présentateur est égal à 1.

3/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Create or replace procedure Q2 is


cursor unProg is
select noPres, nom
from Presentateurs
where noPres in
(select noPresPrincipal
from Programmes
group by noPresPrincipal
having count(*) = 1);
Begin
Dbms_output.put_line('Numéro présentateur ----- Nom présentateur') ;
For C in unProg loop
Dbms_output.put_line(C.noPres||' '|| C.nom) ;
End loop;
End;
/

La requête du curseur peut être définie directement sans utiliser une requête imbriquée :
cursor unProg is
select p.noPres, p.nom
from Presentateurs p, Programmes g
where p.noPres = g.noPresPrincipal
group by p.noPres, p.nom
having count(*) = 1;

Q3. Définir un programme PL/SQL nommé permettant de savoir si deux invités ont participé à
des émissions chez les mêmes présentateurs principaux.
1ère Solution:
Ecrire une fonction qui prend en argument les noInv de deux invités function Q3(inv1 integer,
inv2 integer) et qui retourne true si ces invités ont participé à des émissions des mêmes
présentateurs principaux; si non, elle retourne false.
Trouver le nombre de présentateurs principaux dont le premier invité a participé à leurs
émissions et le deuxième invité n’a pas participé à ces émissions:
Select count(distinct noPresPrincipal) into Nb1
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv1
and noPresPrincipal not int (Select noPresPrincipal
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv2);

On effectue aussi la même chose pour le deuxième invité :


Select count(distinct noPresPrincipal) into Nb2
………………….
Si nb1 et nb2 sont zéro, ceci signifie que les deux invités ont participé exactement à des émissions de
mêmes présentateurs et la fonction retourne true; si non, la fonction retourne false.

4/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Create or replace function Q3(inv1 integer, inv2 integer) return boolean is


Nb1 integer ;
Nb2 integer ;
Begin
Select count(distinct noPresPrincipal) into Nb1
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv1
and noPresPrincipal not int (Select noPresPrincipal
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv2);
Select count(distinct noPresPrincipal) into Nb2
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv2
and noPresPrincipal not int (Select noPresPrincipal
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv1);
return (Nb1 = 0) and (Nb2 = 0) ;
End;
/
Au lieu de répéter la même requête, on peut mettre la requête dans une fonction et faire appel
à cette fonction depuis la fonction principale.
Create or replace function calculer(X integer, Y integer) return integer is
Nbr integer;
Begin
Select count(distinct noPresPrincipal) into Nbr
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = X
and noPresPrincipal not int (Select noPresPrincipal
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = Y);
return Nbr;
End;

Create or replace function Q3(inv1 integer, inv2 integer) return boolean is


Nb1 integer ;
Nb2 integer ;
Begin
Nb1 : = calculer(inv1, inv2);
Nb1 : = calculer(inv2, inv1);
return (Nb1 = 0) and (Nb2 = 0) ;
End;
5/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

2ème Solution:
Au lieu de trouver le nombre de présentateurs principaux pour chacun des invités, on cherche
les numéros de présentateurs principaux pour chacun d’eux et on fait une comparaison pour
vérifier s’il s’agit des mêmes présentateurs.

Create or replace function Q3(inv1 integer, inv2 integer) return boolean is


Cursor invite1 is
Select distinct noPresPrincipal
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv1
order by noPresPrincipal;

Cursor invite2 is
Select distinct noPresPrincipal
from Programmes p, Emissions e, Participe a
where p.noProg = e.noProg and e.noEm = a.noEm
and a.noInv = inv2
order by noPresPrincipal;

P1 integer;
P2 integer;
Begin
Open invite1;
Open invite2;
Loop
Fetch invite1 into p1;
Fetch invite2 into p2;
If (invite1%notfound and invite2%notfound) return true; end if;
If (invite1%notfound or invite2%notfound) return false; end if;
If (p1 != p2) return false; end if;
End loop;
End;
/

Q4. Définir un bloc PL/SQL nommé affichant les noms des programmes dont la durée totale de
toutes ses émissions est la plus longue.

1ère Solution:
Créer un curseur pour trouver la durée totale des émissions de chaque programme, parcourir
le curseur et comparer la durée de chaque programme avec la durée la plus longue afin
d’afficher le nom de ce programme s’il possède la durée la plus longue.
Durée totale des émissions d’un programme = nombre des émissions du programme
multiplié par la durée du programme.

6/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Create or replace procedure Q4 is


Cursor prog is select p.noProg, p.nom , (count(*) * durée) as dureeEms
From Programmes p , Emissions e
p.noProg = e.noProg
group by p.noProg, p.nom;
longDuree integer;
begin
Select max(count(*) * durée) into longDuree
From Programmes p , Emissions e
p.noProg = e.noProg
group by p.noProg;

for C in prog loop


if (c.dureeEms = longDuree)
Dbms_output.put_line(C.nom) ;
end if;
end loop;
end;
/

2ème Solution:
Calculer la durée la plus longue comme une requête imbriquée dans la définition du curseur.

Create or replace procedure Q4 is


Cursor prog is select p.noProg, p.nom
From Programmes p , Emissions e
p.noProg = e.noProg
group by p.noProg, p.nom
having , (count(*) * durée)
= ( Select max(count(*) * durée)
From Programmes a , Emissions b
a.noProg = b.noProg
group by a.noProg);
begin
for C in prog loop
Dbms_output.put_line(C.nom) ;
end loop;
end;
/

7/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Q5. Définir un programme PL/SQL nommé permettant d’afficher les noms des invités qui ont
participé à tous les programmes.

1ère Solution:
Même raisonnement que Q4 ; créer un curseur permettant de trouver pour chaque invité le
nombre de programmes dont il a participé, parcourir ce curseur et comparer le nombre de
programmes de chaque invité avec le nombre total de programmes.

Create or replace procedure Q5 is


Cursor invitesC is
select i.noInv, i.nom, i.prenom, count(distinct noProg) as nbrProg
From Invites i , Participe p, Emissions e
i.noInv = p.noInv and p.noEm = e.noEm
group by i.noInv, i.nom, i.prenom;
nbrTotal integer;
begin
Select count(*) into nbrTotal
From Programmes;

for C in invitesC loop


if (c.nbrProg = nbrTotal)
Dbms_output.put_line(C.nom || ' ' || c.prenom) ;
end if;
end loop;
end;
/

2ème Solution:
Créer un curseur permettant de trouver chaque invité si le nombre de programmes dont il a
participé, est égal le nombre total de programmes.

Create or replace procedure Q5 is


Cursor invitesC is
select i.noInv, i.nom, i.prenom, as nbrProg
From Invites i , Participe p, Emissions e
i.noInv = p.noInv and p.noEm = e.noEm
group by i.noInv, i.nom, i.prenom
having count(distinct noProg) = (Select count(*)
From Programmes );
begin
for C in invitesC loop
Dbms_output.put_line(C.nom || ' ' || c.prenom) ;
end loop;
end;
/

8/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Exercice 2 : (2 pts)
Considérons le schéma relationnel suivant :
Websites (idweb, url, #nbvisite)
Langues (idlang, description)
Pages (idpage, nom,#idlang, #idweb)
Membres (idmemb, nom, prenom, login, adresse)
visites (idvisit, datev, duree, #idpage, #idmemb)

Q1. Trouver un plan d'exécution logique optimal pour la requête suivante :


Select m1.prenom, m1.nom
from membres m1, membres m2, visites v1, visites v2, pages p
where v1.idpage=p.idpage and v1.idmemb= m1.idmemb
and m1.adresse=m2.adresse and m2.idmemb=v2.idmemb
and v2.idpage in (1,2,3) ;

Solution:
Pour trouver un plan logique optimal, on applique un algorithme permettant de réduire le plus
rapidement possible la taille des relations manipulées. Donc :
1. On effectue les sélections (σ) d’abord car on considère que c’est l’opérateur le plus “réducteur”.
2. On élimine dès que possible les attributs inutiles par projection (π).
3. Enfin on effectue les jointures ().

π nom, prenom

adresse

π adresse, nom, prenom


π adresse
idMemb π idMemb
idMemb

π idMemb (V2) idPage

σ (V2) π (M2) π (M1) π (V1) π (P)


idPage in(1, 2, 3) idMemb, adresse idMemb, adresse, idPage, idMemb idPage
nom, prenom

V2 M2 M1 V1 P

9/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Exercice 3 : indexation (6 pts)


Considérons la table Pays (idpays, nom, continent) qui possède comme clé idpays ; et supposons
l’arrivé successive des articles possédant les clés suivantes :
5, 17, 3, 12, 15, 6, 4, 2, 10, 26, 1, 55, 77, 88, 11, 14 et 13.
Q1. Donner l’index non-dense (une page contient 3 pays), et l’arbre B+ d’ordre 2.
Solution
Index non-dense
L’index est un tableau d’éléments dont chaque élément correspond à une page et il est constitué de la
clé du premier article de la page et l’adresse de la page.
Les articles dans les pages doivent être triés suivant les valeurs des clés.

1, @ P0 4, @ P1 10, @ P2 13, @ P3 17, @ P4 77, @ P5

1 4 10 13 17 77
2 5 11 14 26 88
3 6 12 15 55

Arbre B+ d’ordre 2
Chaque nœud de l’arbre (à l’exception de la racine) doit contenir N articles tel que K <= N <=2K
(K est l’ordre de l’arbre). Les feuilles sont enchainées (chaque feuille contient l’adresse de la feuille
suivante) et elles contiennent les clés des articles avec les adresses de pages où se trouvent les articles
ou les articles eux-mêmes (cas exceptionnel où les articles et l’index sont sauvegardés ensemble).
Les autres nœuds contiennent les clés des articles avec les adresses de nœud-enfants.

12

3 5 15 26

1 2 3 4 5 6 10 11 12 13 14 15 17 26 55 77 88

Q2. Nous supposons que la taille d’une ligne est 35 octet dont 6 est dédiée à la clé, l’adresse
d’une ligne est 2 octet et l’adresse d’une page est 3 octet. Calculer les tailles des indexes
donné dans la question Q1.

Solution
Taille de l’index non-dense
L’index contient 6 entrées, alors :
Taille de l’index = 6 * (taille de clé + taille de l’adresse de page)
= 6 * (6 + 3) = 54 octets.

Taille de l’arbre B+
L’arbre contient 3 niveaux :
Taille du 1er niveau (racine) = taille de clé + (2 * taille de l’adresse de page)
= 6 + ( 2 * 3) = 12 octets

10/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Taille du 2ème niveau = (4 * taille de clé) + (6 * taille de l’adresse de page)


= (4 * 6) + ( 6 * 3) = 42 octets
ème
Taille du 2 niveau = (17 * taille de clé)
+ (17 * taille de l’adresse de page de données)
+ (5 * taille de l’adresse de page (feuille voisine))
= (17 * 6) + ( 17 * 3) + (5 * 3) = 168 octets

Taille de l’arbre B+ = 12 + 42 + 168 = 222 octets.

Q3. Montrer l’évolution de l’index de type arbre B+ après suppression des clés suivantes :
d’abord 11, puis 12, puis 13.
Solution
La suppression de l’article de clé 11 n’implique pas de changement ;
La suppression de l’article de clé 12 implique le changement du contenu de racine : 10
remplace 12;
La suppression de l’article de clé 13 n’implique pas de changement ;

10

3 5 15 26

1 2 3 4 5 6 10 14 15 17 26 55 77 88

Exercice 4 : transactions (4 pts)


Partie A : Soit l’exécution concurrente de trois transactions suivantes,
r1[x] r2[y] w1[x] r2[z] r3[z] r3[x] w2[z] r1[z] c2 w1[x] c1 w3[x] c3.
Q1. Vérifier si l’exécution est sérialisable, en construisant son graphe de sérialisation.

Solution
Les conflits:
Sur x: r1[x] -w3[x]
w1[x] -r3[x]
w1[x] -w3[x]
r3[x] –w1[x]
Sur y : Pas de conflits
Sur x: r3[z] –w2[z]
w2[z] –r1[z]

Graphe de Sérialisation

T2 T3

T1

Il y a des cycles  Exécution non sérialisable

11/12
ISAE – Beyrouth, Centre associé au CNAM-Paris
Systèmes de gestion de bases de données – NFP107–
Corrigé de l’examen final 2014

Abdallah EL Asmar

Q2. Quel est le niveau de recouvrabilité de cette exécution ? Expliquer.


Solution
L’exécution est recouvrable (en premier niveau) puisqu’il n’existe pas une situation de type :
Tj lit une donnée déjà écrite par Ti , et Tj se termine avant Ti
Les deux situations à étudier :
w1[x] -r3[x]
w2[z] –r1[z]
Dans les deux cas la transaction effectuant la lecture se termine après celle qui effectue
l’écriture.
L’exécution n’évite pas les annulations en cascade puisque dans les deux cas cités
précédemment, la lecture est effectuée avant la fin de la transaction qui a effectué l’écriture.

Partie B : Soit l’exécution concurrente de trois transactions suivantes,


r1[x] r2[y] w3[x] w1[y] w1[x] w2[y] c2 r3[y] r1[y] c1 w3[y] c3.
Q1. Trouver l’exécution produite par verrouillage à deux phases.

Solution
Verrouillage à 2 phases :

r1[x]  Exécutée
r2[y]  Exécutée
w3[x]  Bloquée, T3 est mise en attente de T1
w1[y]  Bloquée, T1 est mise en attente de T2
w1[x]  Bloquée, (T1 est déjà en attente)
w2[y]  Exécutée
c2  Commit de T2  Verrou de y est relâché  T1 débloquée
w1[y]  Exécutée
w1[x]  Exécutée
r3[y]  Bloquée, (T3 est déjà en attente)
r1[y]  Exécutée
c1  Commit de T1  Verrous de x et y sont relâchés  T3 débloquée
w3[x]  Exécutée
r3[y]  Exécutée
w3[y]  Exécutée
c3 Commit de T3  Verrous de x et y sont relâchés T3 débloquée

Ordre d’exécution :
r1[x] r2[y] w2[y] c2 w1[y] w1[x] r1[y] c1 w3[x] r3[y] w3[y] c3

12/12

Vous aimerez peut-être aussi

pFad - Phonifier reborn

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

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


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy