Exercice 1

Répondre à ce QCM (prendre un peu de temps pour comprendre les explications).

Exercice 2

Écrire une requête effectuant la division relationnelle. Chercher à l'optimiser (EXPLAIN QUERY PLAN + .timer)

Application : noms des acteurs ayant joué à la fois dans des films de Luc Besson et de John McTiernan (base "cinéma" du TP 3).

Solution

Version pas vraiment optimale... (pourquoi ?)

SELECT prenom, nom
FROM
  (SELECT DISTINCT a1.nom, a1.prenom, f.idmes
  FROM role r
  JOIN film f on r.idfilm = f.idfilm
  JOIN artiste a1 on a1.idartiste = r.idacteur
  WHERE f.idmes in
    (SELECT a2.idartiste
    FROM artiste a2
    WHERE a2.nom in ('Besson','McTierman')))
GROUP BY prenom, nom
HAVING count(*) == 2;

Correspond à celle du paragraphe 8. dans cet article, que vous êtes invités à lire ; en particulier la solution du paragraphe 6.

...qui est fausse ! Mais peut être corrigée :

SELECT DISTINCT VILLE_ETP
FROM T_ENTREPOT AS ETP1
WHERE
  (select count(*) from
    (SELECT RAYON_RYN FROM T_RAYON
      intersect
    SELECT RAYON_RYN
    FROM T_ENTREPOT AS ETP2
    WHERE ETP1.VILLE_ETP = ETP2.VILLE_ETP))
  =
    (SELECT COUNT(DISTINCT RAYON_RYN)
    FROM T_RAYON RYN);

Ou mieux :

SELECT DISTINCT VILLE_ETP
FROM T_ENTREPOT AS ETP1
WHERE
  (SELECT RAYON_RYN FROM T_RAYON
    EXCEPT
  SELECT RAYON_RYN
  FROM T_ENTREPOT AS ETP2
  WHERE ETP1.VILLE_ETP = ETP2.VILLE_ETP) IS NULL
-- Pour essayer sur l'exemple de l'article :
CREATE TABLE T_RAYON (
  RAYON_RYN  CHAR(16)
);
CREATE TABLE T_ENTREPOT (
  VILLE_ETP  CHAR(16),
  RAYON_RYN  CHAR(16)
);
INSERT INTO T_RAYON (RAYON_RYN) VALUES
  ('frais'),
  ('boisson'),
  ('conserve'),
  ('droguerie');
INSERT INTO T_ENTREPOT (VILLE_ETP, RAYON_RYN) VALUES
  ('PARIS', 'boisson'),
  ('PARIS', 'frais'),
  ('PARIS', 'conserve'),
  ('LYON', 'boisson'),
  ('LYON', 'conserve'),
  ('LYON', 'droguerie'),
  ('MARSEILLE', 'boisson'),
  ('MARSEILLE', 'frais'),
  ('MARSEILLE', 'conserve'),
  ('MARSEILLE', 'droguerie'),
  ('ANGERS', 'boisson'),
  ('ANGERS', 'frais'),
  ('ANGERS', 'droguerie'),
  ('TOULOUSE', 'boisson'),
  ('TOULOUSE', 'frais'),
  ('TOULOUSE', 'conserve'),
  ('TOULOUSE', 'droguerie');

Exercice 3

Implémenter les trois types d'algorithmes de jointure, et les comparer. Rappel :

  • NESTED : pour chaque ligne de la première table, chercher les lignes correspondantes dans l'autre
  • HASH : utiliser une structure intermédiaire (Python "dictionary") pour stocker la table la plus petite
  • MERGE : d'abord trier selon la condition de jointure (si ce n'est déjà fait)

On pourra utiliser des tableaux d'objets ("dictionaires") en Python par exemple, pour simuler une table. Pour tester les algorithmes sur des tables "déjà triées selon l'index" il suffit de ne pas prendre en compte le tri dans le calcul de perf.

Solution

TODO :)