« On veut gérer les livres d’une bibliothèque : chaque livre a un titre, un auteur, et sait s’il est disponible ou emprunté. On veut pouvoir lister les livres, en ajouter, en supprimer. »
Étape A — la version « structures en mémoire ». Exemple en pseudo-Python orienté objet en utilisant des listes :
class Auteur:
def __init__(self, id, prenom, nom):
self.id, self.prenom, self.nom = id, prenom, nom
class Livre:
def __init__(self, id, titre, auteur, disponible=True):
self.id, self.titre, self.auteur, self.disponible = id, titre, auteur, disponible
auteurs = [Auteur(1, "George", "Orwell"), ...]
livres = [Livre(1, "1984", auteurs[0], disponible=False), ...]Questions :
livres en même temps ? → l’une écrase l’autre, ou on
obtient un état incohérent (problème de
concurrence).auteurs[0] alors
qu’un livre le référence ? → le livre pointe vers un objet qui
n’existe plus, ou il faut écrire du code de vérification partout
(problème d’intégrité).Étape B — la version « fichiers ». : sérialiser dans un fichier CSV ou JSON.
id,titre,auteur_id,disponible
1,1984,1,0Cela règle partiellement la persistance, mais aggrave les deux autres problèmes :
concurrence : deux processus qui écrivent le fichier en même temps → corruption ou perte de la dernière écriture ;
intégrité : rien n’empêche d’écrire auteur_id=42
alors qu’aucun auteur 42 n’existe ; c’est au code applicatif de tout
vérifier, à chaque lecture, dans chaque programme ;
en prime : recherche lente (parcours linéaire), pas de types, pas de transactions.
Conclusion de la mise en situation :
| Problème | En mémoire | En fichier | Ce qu’on attend d’un SGBD |
|---|---|---|---|
| Persistance | ✗ | ✓ (fragile) | ✓ robuste |
| Concurrence | ✗ | ✗ | ✓ (transactions, verrous) |
| Intégrité | ✗ | ✗ | ✓ (contraintes déclaratives) |
| Recherche | ✓ (en RAM) | ✗ | ✓ (index) |
| Requêtes ad hoc | code à écrire | code à écrire | ✓ (SQL) |
D’où l’intérêt de la SGBD.
SGBD (Système de Gestion de Base de Données) : le logiciel qui stocke, sécurise, interroge et garantit l’intégrité des données. Exemples : MariaDB/MySQL, PostgreSQL, SQLite, Oracle. On précise : le SGBD n’est pas la base ; c’est le moteur.
Base de données : ici, l’ensemble nommé
bibliotheque qui regroupe les tables et leur contenu, géré
par le SGBD.
Schéma : la description de la structure —
quelles tables, quelles colonnes, quels types, quelles contraintes.
C’est le « plan » de la base, distinct des données. deux fichiers :
schema.sql (le plan) et data.sql (le
contenu).
Table : un ensemble de données du même type. Ici
auteur et livre. Faites le parallèle avec la
classe : une table ≈ la définition d’une classe ; une ligne ≈
une instance.
Ligne (enregistrement / tuple) : un élément de la table. Exemple concret :
(1, '1984', 1, 0)
Colonne (attribut / champ) : une propriété de la
table, avec un type. CREATE TABLE livre
:
id INT NOT NULL AUTO_INCREMENT
titre VARCHAR(200) NOT NULL
auteur_id INT NOT NULL
disponible TINYINT(1) NOT NULL DEFAULT 1
INT pour les identifiants et la clé étrangère,
VARCHAR(200) pour les textes de longueur variable,
TINYINT(1) comme booléen (convention MySQL/MariaDB à
connaître).
Clé primaire : la colonne qui identifie de façon
unique une ligne. Dans auteur c’est id, dans
livre c’est id. On insiste : unique
(deux auteurs ne peuvent pas avoir le même id) et non nulle
(pas de ligne sans identifiant). On fait le lien avec un attribut
d’identité dans un objet.
Clé étrangère : une colonne qui référence
la clé primaire d’une autre table. Dans livre,
auteur_id référence auteur.id. C’est ce qui
matérialise la relation « un livre a un auteur » et
permet au SGBD de refuser un livre dont l’auteur n’existe pas.
On peut faire un mini-schéma :
auteur livre
┌────┬────────┬──────────┐ ┌────┬─────────────────┬───────────┬────────────┐
│ id │ prenom │ nom │ │ id │ titre │ auteur_id │ disponible │
├────┼────────┼──────────┤ ├────┼─────────────────┼───────────┼────────────┤
│ 1 │ George │ Orwell │◄─────│ 1 │ 1984 │ 1 │ 0 │
│ 4 │ Jules │ Verne │◄─────│ 4 │ Vingt mille... │ 4 │ 1 │
│ 11 │ Erskine│ Caldwell │ │ 6 │ Voyage au... │ 4 │ 1 │
└────┴────────┴──────────┘ └────┴─────────────────┴───────────┴────────────┘
PK: id PK: id FK: auteur_id → auteur.id
On fait remarquer deux choses sur les données :
auteur mais est
référencé par deux livres → c’est tout l’intérêt de la
séparation : on ne duplique pas « Jules Verne » dans chaque ligne de
livre ;SQL : le langage pour interroger et manipuler. Nous
verrons bientôt : SELECT (séances 3–4),
INSERT/UPDATE/DELETE (séance 5), sous-requêtes et vues (6),
droits (7), puis usage depuis le code (8).
Analyse et compréhension ligne par ligne :
CREATE TABLE auteur (
id INT NOT NULL AUTO_INCREMENT,
prenom VARCHAR(100) NOT NULL,
nom VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);Questions guidées :
NOT NULL sur prenom ? →
interdit une valeur absente ;AUTO_INCREMENT ? → le SGBD attribue l’id
automatiquement (on reverra les implications en séance 5 avec
LAST_INSERT_ID()) ;PRIMARY KEY (id) → identifiant unique et non nul.CREATE TABLE livre (
id INT NOT NULL AUTO_INCREMENT,
titre VARCHAR(200) NOT NULL,
auteur_id INT NOT NULL,
disponible TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (id),
KEY idx_livre_auteur (auteur_id),
CONSTRAINT fk_livre_auteur
FOREIGN KEY (auteur_id) REFERENCES auteur (id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);Questions guidées :
DEFAULT 1 sur disponible → si on n’indique
rien à l’insertion, le livre est considéré disponible ;FOREIGN KEY (auteur_id) REFERENCES auteur(id) → un
auteur_id saisi doit exister dans auteur
;ON DELETE RESTRICT → on ne peut pas
supprimer un auteur tant qu’il a des livres (on le testera en séance 5,
c’est volontaire) ;KEY idx_livre_auteur (auteur_id) → on annonce
simplement qu’il s’agit d’une structure d’accélération (index), qu’on
étudiera en séance 9. Pas besoin d’expliquer le B-tree maintenant.Synthèse :
| Table | Colonnes | Clé primaire | Clé(s) étrangère(s) | Contraintes notables |
|---|---|---|---|---|
auteur |
id, prenom, nom | id |
— | prénom et nom obligatoires |
livre |
id, titre, auteur_id, disponible | id |
auteur_id → auteur.id |
suppression d’auteur restreinte ; disponible par défaut |
Message clé : le schéma porte une partie des règles métier (unicité, existence de l’auteur, valeur par défaut). C’est du code déclaratif que le SGBD fait respecter pour tous les programmes, contrairement au code applicatif qui ne protège que l’application qui l’exécute.
Livrable : un fichier
compte_rendu_seance1.txt contenant les réponses aux
questions numérotées et les captures de sortie demandées. Le TP est
conçu pour être faisable sans connaissance SQL préalable ; toutes les
commandes sont fournies, vous devez les exécuter, observer et
commenter.
Selon l’environnement :
mariadb --version (ou
mysql --version) ; c’est notre cas!Commande de connexion :
sudo mariadbUne fois dans le client (avec le prompt MariaDB [(none)]> ), on vérifie le serveur :
MariaDB [(none)]> SELECT VERSION();
+--------------------------------------+
| VERSION() |
+--------------------------------------+
| **.*.*-MariaDB-0+deb13u1 from Debian |
+--------------------------------------+
1 row in set (0,001 sec)
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| phpmyadmin |
| sys |
+--------------------+Q0 : quelle version du SGBD utilisez-vous ? Combien de bases sont déjà présentes sur le serveur ?
Comme nous allons le voir il est possible d’envoyer des requêtes SQL
en ligne de commande. Vérifier que vous avez bien les fichiers
schema.sql et data.sql demandés puis tapez les commandes suivantes dans
une Konsole (pas dans le client mariadb) :
sudo mariadb -e "CREATE DATABASE bibliotheque;"
sudo mariadb bibliotheque < schema.sql
sudo mariadb bibliotheque < data.sqlVous avez créé une nouvelle base de données bibliotheque ; importé dans cette base la structure décrite par schema.sql, puis rempli cette structure avec les données fournies par data.sql. Ces fichiers sont lisibles, vous pouvez les ouvrir avec kate pour visualiser leur contenu. Puis, dans le client, selectionnez la base bibliotheque et demandez à voir les Tables associées :
MariaDB [(none)]> USE bibliotheque;
MariaDB [bibliotheque]> SHOW TABLES;
+------------------------+
| Tables_in_bibliotheque |
+------------------------+
| auteur |
| livre |
+------------------------+
2 rows in set (0,000 sec)
MariaDB [bibliotheque]> Q1 : combien de tables contient la base
bibliotheque ? Listez-les.
Q2 : que se passerait-il si vous relanciez
schema.sql une deuxième fois ? (indice : regardez la
première ligne du fichier)
a) Description des tables.
Réflechissez à l’endroit où vous devez vous placer pour exécuter les commandes suivantes :
DESCRIBE auteur;
DESCRIBE livre;
-- variante équivalente :
SHOW COLUMNS FROM livre;Q3 : recopiez la sortie de
DESCRIBE livre. Identifiez pour chaque colonne : type,
nullabilité, valeur par défaut, rôle (clé primaire, clé étrangère,
index).
Q4 : DESCRIBE vous montre-t-il la
contrainte de clé étrangère ? Sinon, quelle commande utilisez-vous ?
(indice : SHOW CREATE TABLE livre;)
b) Exploration des métadonnées via
information_schema.
information_schema est une base « système » qui décrit
les autres bases. On peut donc l’interroger en SQL comme n’importe
quelle table. On l’a vue suite à la commande SQL ‘SHOW DATABASES;’
-- Toutes les tables de la base bibliotheque
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = 'bibliotheque';
-- Toutes les colonnes de toutes les tables de la base
SELECT table_name, column_name, data_type, is_nullable, column_default, column_key
FROM information_schema.columns
WHERE table_schema = 'bibliotheque'
ORDER BY table_name, ordinal_position;
-- Les clés primaires et étrangères
SELECT table_name, constraint_name, constraint_type
FROM information_schema.table_constraints
WHERE table_schema = 'bibliotheque';Q5 : quelle table de bibliotheque a le
plus de colonnes ? Lesquelles ?
Q6 : d’après la requête sur
table_constraints, quelles contraintes existe-t-il dans la
base ? Classez-les par type (PRIMARY KEY,
FOREIGN KEY, UNIQUE…).
Q7 : la colonne column_key dans
information_schema.columns vaut PRI pour la
clé primaire et MUL pour une colonne indexée. Vérifiez-le
sur livre. Que constatez-vous pour auteur_id
?
c) Visualisation du schéma. Si un client graphique
est disponible (DBeaver, phpMyAdmin), demander une capture du diagramme
relationnel généré. Sinon, redessiner au propre le
schéma (deux boîtes, une flèche auteur_id → auteur.id). Il
est toujours bon de savoir que des outils graphiques existent mais ils
sont peu pratiques ; il est tellement plus rapide de relire, modifier et
lancer une commande ou un script!
Q8 : joignez le diagramme (capture ou dessin). Combien de relations y voyez-vous ? De quel type (1-1, 1-N, N-N) ?
On ne demande aucune écriture : uniquement de l’observation, pour rester dans l’objectif de la séance.
SELECT * FROM auteur;
SELECT * FROM livre;Q9 : combien y a-t-il de lignes dans chaque table ?
Quelle commande avez-vous utilisée pour le vérifier autrement que « à
l’œil » ? (réponse : SELECT COUNT(*) FROM ...)
Q10 : identifiez, dans la table auteur,
un auteur qui n’apparaît dans aucun livre. Quelle est la valeur de son
id ? Expliquez, en une phrase, pourquoi le SGBD autorise ce
cas.
Q11 : identifiez un livre indisponible. Quelle colonne et quelle valeur permettent de le savoir ?
Q12 : dans la table livre, combien de
livres sont associés à l’auteur d’id = 4 ? Quelle commande
avez-vous écrite pour le savoir ? (indice :
WHERE auteur_id = 4 — même si WHERE sera vu
formellement en séance 3, on l’autorise ici comme lecture)
C’est le moment de voir le SGBD refuser une
opération incohérente. On prévient : l’objectif n’est pas d’apprendre
INSERT/DELETE (séance 5), mais d’observer le
comportement.
-- 1. Tenter d'insérer un livre avec un auteur inexistant (id 999)
INSERT INTO livre (titre, auteur_id) VALUES ('Livre fantôme', 999);
-- 2. Tenter de supprimer un auteur qui a des livres (Jules Verne, id 4)
DELETE FROM auteur WHERE id = 4;
-- 3. Tenter d'insérer un auteur sans nom
INSERT INTO auteur (prenom) VALUES ('Anonyme');Q13 : pour chaque commande, recopiez le message
d’erreur renvoyé et expliquez quelle contrainte du
schéma l’a provoqué (clé étrangère ? NOT NULL ? autre
?).
Q14 : après ces trois tentatives, vérifiez avec
SELECT COUNT(*) que la base n’a pas été
modifiée. Conclusion : que garantit le SGBD même quand le code
applicatif se trompe ?
Q15 : en 5 à 8 lignes, répondez à la question « pourquoi une base de données relationnelle plutôt que des fichiers ou des structures en mémoire ? », en vous appuyant sur au moins trois observations concrètes faites pendant ce TP (persistance, refus d’une donnée incohérente, métadonnées interrogeables, séparation schéma/données…).
CREATE TABLE de livre et repérer
les mots-clés qu’on n’a pas encore expliqués (CONSTRAINT,
ON UPDATE CASCADE) — on les traitera en séance 2.Question : Citez les trois limites principales d’un stockage des données en mémoire vive (structures de type listes/objets), et expliquez brièvement chacune.
Question : Le passage d’un stockage en mémoire à un stockage en fichiers règle-t-il tous les problèmes ? Justifiez en indiquant ce qu’il améliore et ce qu’il aggrave.
Non. Le stockage en fichier (CSV, JSON) règle partiellement
la persistance, mais aggrave la concurrence
(deux processus qui écrivent le même fichier en même temps peuvent le
corrompre ou perdre la dernière écriture) et ne règle pas
l’intégrité (rien n’empêche d’écrire un auteur_id
qui n’existe pas ; c’est au code applicatif de tout vérifier). Il ajoute
aussi d’autres défauts : recherche lente (parcours linéaire), absence de
types, absence de transactions.
Question : Définissez le SGBD et distinguez-le de la base de données elle-même.
Le SGBD (Système de Gestion de Base de Données) est
le logiciel/moteur qui stocke, sécurise, interroge et
garantit l’intégrité des données (ex. : MariaDB, MySQL, PostgreSQL,
SQLite, Oracle). La base de données est
l’ensemble nommé de tables et de données géré par ce
moteur (ici la base bibliotheque). Le SGBD n’est donc pas
la base : c’est l’outil qui la gère.
Question : Qu’appelle-t-on le schéma d’une base ? Comment se distingue-t-il des données, et quels sont les deux fichiers fournis qui illustrent cette séparation ?
Le schéma est la description de la structure :
quelles tables, quelles colonnes, quels types, quelles contraintes.
C’est le « plan » de la base. Les données sont le
contenu effectivement stocké dans ces tables. Dans le TP, cette
séparation est illustrée par schema.sql (le plan : les
CREATE TABLE et contraintes) et data.sql (le
contenu : les lignes insérées).
Question : Associez chaque terme à sa définition : table, ligne, colonne, clé primaire, clé étrangère.
auteur,
livre.(1, '1984', 1, 0).titre VARCHAR(200).auteur.id, livre.id).livre.auteur_id → auteur.id), matérialisant ainsi la
relation.Question : Dans le schéma fourni, quelle colonne de
la table livre est une clé étrangère, et vers quelle
colonne pointe-t-elle ? Quel est l’intérêt de cette contrainte pour le
SGBD ?
C’est la colonne auteur_id de
livre, qui référence
auteur.id. Grâce à cette contrainte de clé
étrangère, le SGBD refuse l’insertion d’un livre dont
l’auteur n’existe pas (par exemple auteur_id = 999). Elle
matérialise la relation « un livre a un auteur » et garantit l’intégrité
référentielle sans que chaque programme applicatif ait à la
vérifier.
Question : Que signifie la mention
AUTO_INCREMENT sur la colonne id d’une table ?
Et que signifie DEFAULT 1 sur la colonne
disponible de livre ?
AUTO_INCREMENT : le SGBD attribue
automatiquement la valeur de l’identifiant à l’insertion ; on
n’a pas à fournir la valeur d’id soi-même.DEFAULT 1 : si aucune valeur n’est fournie pour
disponible lors de l’insertion, le SGBD utilise
1 par défaut (le livre est considéré comme
disponible).Question : Que produisent les clauses
ON DELETE RESTRICT et ON UPDATE CASCADE dans
le CREATE TABLE livre du schéma fourni ?
ON DELETE RESTRICT : on ne peut pas
supprimer un auteur tant qu’il a encore des livres qui le
référencent. Le SGBD refuse l’opération (testé en TP avec Jules Verne,
id 4).ON UPDATE CASCADE : si la valeur de la clé primaire
d’un auteur est modifiée, la modification est
propagée automatiquement à la clé étrangère
auteur_id des livres concernés.Question : Remplissez (mentalement ou sur papier) le tableau d’analyse du schéma : pour chaque table, indiquez ses colonnes, sa clé primaire, ses clés étrangères et une contrainte notable.
| Table | Colonnes | Clé primaire | Clé(s) étrangère(s) | Contrainte notable |
|---|---|---|---|---|
auteur |
id, prenom, nom | id |
— | prénom et nom obligatoires (NOT NULL) |
livre |
id, titre, auteur_id, disponible | id |
auteur_id → auteur.id |
suppression d’auteur restreinte ; disponible vaut 1 par
défaut |
Question : Un auteur apparaît une seule fois dans la
table auteur mais peut être référencé par plusieurs livres.
Quel avantage cela procure-t-il par rapport à un stockage où l’on
écrirait le nom de l’auteur dans chaque ligne de livre
?
Cela évite la duplication des informations sur
l’auteur : on ne répète pas « Jules Verne » dans chaque ligne de
livre, on stocke son identifiant (auteur_id).
On gagne en cohérence (une seule source de vérité pour le nom de
l’auteur : une modification ne se fait qu’à un seul endroit). Cela évite
d’avoir un livre dont l’auteur est « Jules Verne » et un autre dont
l’auteur est « jules Verne ». On gagne aussi en intégrité, tout en
matérialisant la relation « un auteur → plusieurs livres ». C’est tout
l’intérêt de la séparation en deux tables reliées par une clé
étrangère.
Question : Lors du TP, vous avez tenté d’insérer un
livre avec auteur_id = 999. Décrivez le comportement du
SGBD et la contrainte responsable.
Le SGBD refuse l’insertion et renvoie une erreur de
type « violation de contrainte de clé étrangère » (foreign key
constraint fails). La contrainte responsable est la
FOREIGN KEY (auteur_id) REFERENCES auteur(id) : aucun
auteur d’id 999 n’existe, donc la référence est invalide. Après
l’erreur, la base n’a pas été modifiée.
Question : Lors du TP, vous avez tenté de supprimer l’auteur Jules Verne (id 4). Pourquoi le SGBD refuse-t-il ? Que faudrait-il faire pour pouvoir le supprimer légitimement ?
Le SGBD refuse car cet auteur est référencé par des livres et la
contrainte est ON DELETE RESTRICT : on ne peut pas
supprimer une ligne encore référencée par une clé étrangère. Pour le
supprimer légitimement, il faudrait d’abord traiter ses
livres : soit les supprimer, soit les réaffecter à un autre
auteur (modifier leur auteur_id), de sorte qu’aucune ligne
de livre ne référence plus l’id 4.
Question : Lors du TP, vous avez tenté d’insérer un auteur sans fournir de nom. Décrivez la réaction du SGBD et la contrainte en cause.
Le SGBD refuse l’insertion avec une erreur du type «
Column ‘nom’ cannot be null » (ou « doesn’t have a default value »). La
contrainte responsable est le NOT NULL sur
la colonne nom (et prenom) de la table
auteur : une valeur absente est interdite. La base reste
inchangée.
Question : Quelle base « système » permet d’interroger les métadonnées (tables, colonnes, contraintes) d’une base en SQL, et quelles tables de cette base avez-vous utilisées en TP ?
Il s’agit de information_schema, une
base système décrivant les autres bases et interrogeable en SQL comme
n’importe quelle table. En TP, on a notamment utilisé
information_schema.tables (liste et nombre de lignes des
tables), information_schema.columns (colonnes, types,
nullabilité, valeur par défaut, column_key) et
information_schema.table_constraints (clés primaires,
étrangères, unicité…).
Question : Que vous montre la commande
DESCRIBE livre; ? Montre-t-elle la contrainte de clé
étrangère ? Si non, quelle commande permet de la voir ?
DESCRIBE livre; (ou
SHOW COLUMNS FROM livre;) affiche les
colonnes de la table avec leur type,
leur nullabilité, leur valeur par
défaut et leur rôle (column_key :
PRI pour la clé primaire, MUL pour une colonne
indexée comme auteur_id). Elle ne montre
pas la contrainte de clé étrangère elle-même. Pour la voir, on
utilise SHOW CREATE TABLE livre; (qui
affiche le DDL -Data Definition Language- complet, avec la clause
FOREIGN KEY ... REFERENCES ...).
Question : Dans la sortie de
DESCRIBE livre, que signifie la valeur MUL
dans la colonne Key pour auteur_id ? Et
PRI pour id ?
PRI sur id : la colonne
est la clé primaire de la table (unique et non
nulle).MUL sur auteur_id : la
colonne est indexée et peut prendre plusieurs fois la
même valeur (plusieurs livres peuvent avoir le même auteur). Cet index
correspond ici au KEY idx_livre_auteur (auteur_id) déclaré
dans le schéma, et il sert notamment à accélérer les recherches sur
cette colonne.Question : Combien de relations voyez-vous dans le
schéma bibliotheque, et de quel type sont-elles (1-1, 1-N,
N-N) ? Justifiez à l’aide des données.
Il y a une seule relation : entre
auteur et livre, via
livre.auteur_id → auteur.id. Elle est de type
1-N (un auteur peut avoir plusieurs livres ; un livre a
un seul auteur). Les données le confirment : Jules Verne (id 4) est
référencé par deux livres, tandis qu’un livre n’a qu’un
seul auteur_id. Il n’y a pas de relation N-N dans ce
schéma.
Question : En TP, vous avez identifié un auteur n’ayant aucun livre. Pourquoi le SGBD autorise-t-il ce cas, alors qu’il refuse un livre dont l’auteur n’existe pas ?
Parce que la contrainte de clé étrangère ne s’applique que
dans un sens : elle vérifie que tout
auteur_id saisi dans livre
existe dans auteur (intégrité
référentielle côté « livre → auteur »). Elle n’impose
rien sur l’existence de livres pour un auteur donné. Un
auteur sans livre est donc parfaitement valide : la relation n’est pas
obligatoire dans les deux sens. (Ce cas sera exploité en séance 4 avec
les jointures externes LEFT JOIN.)
Question : Comment vérifier « autrement qu’à l’œil » le nombre de lignes d’une table ? Donnez la commande.
On utilise la fonction d’agrégation
COUNT :
SELECT COUNT(*) FROM auteur; et
SELECT COUNT(*) FROM livre;. Cela renvoie le nombre exact
de lignes, contrairement à une lecture visuelle de SELECT *
qui n’est fiable que sur de petits volumes.
Question : Après les trois tentatives d’écriture incohérentes du TP (livre fantôme, suppression d’auteur référencé, auteur sans nom), qu’observez-vous si vous recomptez les lignes ? Que garantit le SGBD même quand le code applicatif se trompe ?
Le recomptage avec SELECT COUNT(*) montre que les tables
n’ont pas été modifiées : les trois opérations ont été
rejetées en bloc. Le SGBD garantit donc que les
contraintes déclaratives du schéma sont toujours respectées,
indépendamment du programme qui l’interroge (même un code applicatif
buggé ne peut pas insérer une donnée incohérente). C’est là tout
l’intérêt du code déclaratif porté par le schéma : il
protège la base pour tous les programmes, contrairement au code
applicatif qui ne protège que l’application qui l’exécute.
Question : Synthèse : en quelques lignes, argumentez le recours à une base de données relationnelle plutôt qu’à des fichiers ou à des structures en mémoire, en vous appuyant sur au moins trois observations concrètes du TP.
Réponse attendue (forme libre, 5 à 8 lignes) articulant au moins trois arguments parmi :
schema.sql /
data.sql et reconnexions).FOREIGN KEY,
ON DELETE RESTRICT, NOT NULL), sans modifier
la base.schema.sql
décrit la structure, data.sql le contenu ; le schéma porte
une partie des règles métier de façon déclarative.information_schema permet d’explorer la structure en SQL,
comme n’importe quelle donnée.Question : En vous appuyant sur le TP, expliquez en une phrase la différence entre « le schéma porte les règles métier » et « le code applicatif porte les règles métier ».
Quand les règles sont dans le schéma (contraintes
NOT NULL, FOREIGN KEY, UNIQUE,
DEFAULT…), le SGBD les fait respecter pour tous les
programmes qui accèdent à la base ; quand elles sont dans le
code applicatif, elles ne protègent que
l’application qui les exécute (un autre programme, un
script d’administration ou un bug peuvent contourner le contrôle).
Question : Question ouverte de préparation (séance 2) : si l’on voulait enregistrer les emprunts de livres dans cette base, quelles tables faudrait-il ajouter, et quelles clés étrangères contiendraient-elles ?
Réponse attendue (amorce, sans exigence formelle) : ajouter au
minimum une table emprunt (ou
emprunt/lecteur) contenant par exemple
id (clé primaire), livre_id (clé étrangère →
livre.id), lecteur_id (clé étrangère →
lecteur.id si l’on ajoute une table lecteur),
ainsi que des dates (date_emprunt,
date_retour). Les clés étrangères garantiraient qu’on
n’enregistre pas un emprunt pour un livre ou un lecteur inexistant.
Cette question prépare la séance 2 (contraintes, types de dates,
NULL pour la date de retour) et le projet intégrateur.