TP3 : Tables et contraintes
Consignes
Création d'une table et contraintes de colonnes
Créez une table ayant pour colonnes : - : une clef primaire auto-increment.
- : un texte dont la valeur par défaut sera .
- : un entier qui ne peut être .
- : un entier impair (utilisez ).
Via une requête SQL affichez le schéma de la table Via une requête SQL affichez la requête SQL de création de la table Insérez 3 entrées dans la table en ne renseignant que les colonnes et . - Affichez les entrées de la table .
Contraintes de tables
Créez une table ayant pour colonnes : - : un entier qui ne peut être .
- : un entier qui doit être supérieur à
Clefs étrangères
⚠ Vous devrez activer les clefs étrangères via la commande
Créez une table ayant pour colonnes : - : une clef étrangère non-nulle vers la table .
Insérez une entrée dans référençant la dernière entrée de . Incrémentez la colonne de l'entrée référencée. Que se passe-t-il ? Pourquoi ? Supprimez l'entrée référencée. Que se passe-t-il ? Pourquoi ? Supprimez la table . - Recommencez les opérations précédentes, cette fois de sorte à ce que la clef étrangères soit supprimée/modifiée lors de la suppression/modification de la clef primaire.
Création de Que se passe-t-il lors de la modification ? Pourquoi ? Que se passe-t-il lors de la suppression ? Pourquoi ?
- Recommencez les opérations précédentes, cette fois de sorte à ce que la clef étrangères soit mise à lors de la suppression de la clef primaire, et modifiée lors de la modification de la clef primaire.
Création de Que se passe-t-il lors de la suppression ? Pourquoi ?
Mesurer la performance des index
⚠ Pour des raisons de performances, vous devrez utiliser une base de données "in memory". Pour cela, lancez une nouvelle instance de SQLite sans préciser ni ouvrir de fichiers.
Nous allons désormais voir à quel point les index sont vitaux lors de requêtes SQL sur de très larges tables. Pour cela nous suivrons le protocole suivant :
- créer 3 tables () :
- table : sans contraintes supplémentaires.
- table : .
- table : .
- remplir ces tables de manière identique, avec = entrées unique.
- pour chaque, mesurer la durée de recherche de l'entrée où .
Création et remplissage des tables
Dans un premier temps, nous créons une table contenant nos entrées :
💡 On ne vous demandera pas de comprendre le fonctionnement de .
Créez les tables et que vous remplirez ensuite à partir de .
Mesurer la durée d'exécution d'une requête
- Activez la mesure de la durée d'exécution des requêtes via .
- Activez l'explication des requêtes via .
- : lis les lignes de la table unes à unes ;
- : recherche des entrées dans la table via un index,
Sur , , et , mesurez la durée d'exécution de la requête suivante : Comment expliquez-vous la différence de résultats entre , et / ? Exécutez sur et , qu'observez-vous ? - Exécutez la requête suivante sur et :
Comment pourriez-vous expliquer la différence sur les temps d'exécution ?
💡 Préfixer une requête SQL par permet de l'expliquer sans l'exécuter.
Créer un INDEX
Comme nous l'avons vu en CM, les SGBD ajoutent un index sur les contraintes . Cela s'explique par le fait qu'à chaque insertions, le SGBD doit vérifier la contrainte, et donc rechercher si la valeur existe déjà dans la(les) colonne(s).
💡 La commande permet d'afficher la liste des index de la table .
- Vérifiez que possède bien un index, et que n'en possède pas.
Créez un index sur via . - Listez les index de , puis exécutez la requête précédente.
Qu'observez-vous quant à la vitesse d'exécution ? Créez une table . - Remplissez cette table via la requête SQL suivante (insère duplicats) :
Mesurez la vitesse d'execution de la requête sur cette table : Créez un index sur cette table. Mesurez à nouveau la vitesse d'execution, qu'observez-vous ?
⚠ Les index ont un coût lors des //, il ne faut pas en abuser.
💡 En réalité, il est rare de devoir créer des index manuellement.