Tables, Clés, Relations et SQL
Bootcode IWA-S04 â Semaine 14, Jour 1
1. Créer des tables
Avec les bons types et contraintes
2. Définir des relations
Avec des clés étrangÚres entre tables
3. Insérer des données
Avec INSERT INTO
4. Lire des données
Avec SELECT
Le problÚme du stockage en mémoire
Tout disparaßt au redémarrage
Qu'est-ce qu'une BDD relationnelle ?
Tables, colonnes, lignes
Vocabulaire
Clé primaire, clé étrangÚre, types de colonnes
Les 3 types de relations
1-1, 1-N, N-N
Installation de PostgreSQL
Premiers pas avec psql
Module 1
Tout disparaßt au redémarrage
Quand votre programme s'arrĂȘte, tout est perdu!
// En JavaScript, vos données sont en mémoire
const etudiants = [
{ nom: "Alice", note: 15 },
{ nom: "Bob", note: 12 },
];
// Le programme s'arrĂȘte â les donnĂ©es disparaissent!
â ïž La RAM est volatile : pas d'Ă©lectricitĂ© = pas de donnĂ©es
// Sauvegarder en JSON
const data = JSON.stringify(etudiants);
fs.writeFileSync('data.json', data);
// Relire au démarrage
const raw = fs.readFileSync('data.json');
const etudiants = JSON.parse(raw);
â ProblĂšmes avec les fichiers :
Un systÚme de stockage persistant, structuré et fiable
đŸ
Persistant
Les données survivent au redémarrage
đ
Recherche rapide
Index et requĂȘtes optimisĂ©es
đ
Contraintes
Validation automatique des données
â Une BDD = stockage + structure + intĂ©gritĂ© + concurrence
Module 2
Tables, colonnes, lignes
InventĂ© par Edgar Codd en 1970 â organiser les donnĂ©es en tables liĂ©es par des relations
Table = une entité
Table
Comme un onglet Excel
Colonne (champ)
Le type d'information (nom, age...)
Ligne (enregistrement)
Une entrée complÚte (Alice, 20)
đ PK = Primary Key (clĂ© primaire)
Identifie chaque ligne de façon unique
đ FK = Foreign Key (clĂ© Ă©trangĂšre)
Référence une ligne dans une autre table
Vous connaissez déjà ce concept en JavaScript!
// La Map en JavaScript
const etudiants = new Map();
// clĂ© â objet (une ligne)
etudiants.set(1, {
nom: "Alice",
age: 20
});
Map = Table
La structure qui contient les données
Clé de la Map = Clé primaire
Identifie chaque entrée de façon unique
L'objet = La ligne
Les donnĂ©es elles-mĂȘmes
đĄ La diffĂ©rence : la BDD est persistante et structurĂ©e, la Map est en mĂ©moire volatile
Module 3
Clé primaire, clé étrangÚre, types de colonnes
Un identifiant unique pour chaque ligne â comme un numĂ©ro de sĂ©curitĂ© sociale
CREATE TABLE etudiants (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL
);
â UNIQUE : pas deux lignes avec le mĂȘme id
â NOT NULL : toujours une valeur
đĄ On prĂ©fĂšre UUID plutĂŽt que auto-increment â pas de devinable, pas de collision
Une rĂ©fĂ©rence vers la clĂ© primaire d'une autre table â crĂ©e la relation
CREATE TABLE etudiants (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
promo_id UUID NOT NULL REFERENCES promos(id)
);
â La FK garantit l'intĂ©gritĂ© rĂ©fĂ©rentielle
Impossible d'insérer un étudiant dans une promo qui n'existe pas!
â Sans FK : donnĂ©es orphelines, incohĂ©rences, bugs silencieux
VARCHAR(n)
Texte de longueur max n
nom VARCHAR(100)
INTEGER
Nombre entier
age INTEGER
UUID
Identifiant unique universel
id UUID DEFAULT gen_random_uuid()
TIMESTAMP
Date et heure
created_at TIMESTAMP DEFAULT NOW()
BOOLEAN
Vrai ou faux
est_actif BOOLEAN DEFAULT true
TEXT
Texte illimité (descriptions longues)
bio TEXT
Les contraintes sont les rÚgles que la BDD vérifie automatiquement
NOT NULL
La colonne doit toujours avoir une valeur
UNIQUE
Pas deux lignes avec la mĂȘme valeur
REFERENCES (Foreign Key)
La valeur doit exister dans l'autre table
DEFAULT
Valeur par défaut si non fournie
â ïž Oublier NOT NULL sur les colonnes obligatoires est une erreur frĂ©quente!
Module 4
1-1, 1-N, N-N
Un enregistrement A est lié à exactement un enregistrement B
// La FK cÎté profil avec UNIQUE pour garantir 1-1
user_id UUID NOT NULL UNIQUE REFERENCES utilisateurs(id)
đĄ La relation 1-1 est rare. On l'utilise pour sĂ©parer des donnĂ©es optionnelles (ex: profil dĂ©taillĂ©)
Un enregistrement A est lié à plusieurs enregistrements B
Exemple : une promo a plusieurs étudiants
⥠RÚgle d'or : la clé étrangÚre va toujours cÎté N
C'est l'étudiant qui a un promo_id, pas la promo qui a un etudiant_id
Plusieurs A sont liĂ©s Ă plusieurs B â nĂ©cessite une table de liaison
// La table de liaison a DEUX clés étrangÚres
CREATE TABLE etudiant_cours (
etudiant_id UUID REFERENCES etudiants(id),
cours_id UUID REFERENCES cours(id),
PRIMARY KEY (etudiant_id, cours_id)
);
Module 5
Premiers pas avec psql
â ïž L'installation varie selon l'OS â prĂ©voir du temps!
đ§ Linux (Ubuntu/Debian)
# Installer
sudo apt install postgresql
# Démarrer
sudo systemctl start postgresql
đ macOS
# Avec Homebrew
brew install postgresql@17
# Démarrer
brew services start postgresql@17
đȘ Windows
# Télécharger l'installeur
postgresql.org/download
# Ou avec WSL
â voir Linux
đĄ AprĂšs installation, PostgreSQL crĂ©e un utilisateur postgres par dĂ©faut
psql = le terminal interactif de PostgreSQL
# Se connecter
sudo -u postgres psql
# Commandes essentielles dans psql
\l â lister les bases de donnĂ©es
\dt â lister les tables
\d nom_table â dĂ©crire une table
\q â quitter psql
# Créer une base pour le cours
CREATE DATABASE bootcode;
CREATE USER student WITH PASSWORD 'pass123';
GRANT ALL PRIVILEGES ON DATABASE bootcode TO student;
Créer une table complÚte : types, contraintes et clé étrangÚre
CREATE TABLE promos (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
annee INTEGER NOT NULL
);
CREATE TABLE etudiants (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
age INTEGER,
est_actif BOOLEAN DEFAULT true,
promo_id UUID NOT NULL REFERENCES promos(id),
created_at TIMESTAMP DEFAULT NOW()
);
Ajouter des lignes dans une table
-- D'abord la promo (elle doit exister avant l'étudiant)
INSERT INTO promos (nom, annee)
VALUES ('IWA-S04', 2025);
-- Puis les étudiants
INSERT INTO etudiants (nom, email, age, promo_id)
VALUES ('Alice', '[email protected]', 20,
(SELECT id FROM promos WHERE nom = 'IWA-S04'));
đĄ On utilise un SELECT pour rĂ©cupĂ©rer l'id de la promo â pas besoin de le connaĂźtre!
-- Insertion multiple
INSERT INTO etudiants (nom, email, promo_id)
VALUES
('Bob', '[email protected]', ...),
('Charlie', '[email protected]', ...);
-- Tous les étudiants
SELECT * FROM etudiants;
-- Colonnes spécifiques
SELECT nom, email FROM etudiants;
-- Avec un filtre
SELECT * FROM etudiants
WHERE age > 18;
-- Trié par nom
SELECT * FROM etudiants
ORDER BY nom ASC;
-- Jointure : étudiants avec leur promo
SELECT e.nom, p.nom AS promo
FROM etudiants e
JOIN promos p ON e.promo_id = p.id;
đĄ Le JOIN utilise la clĂ© Ă©trangĂšre pour relier les tables â c'est la puissance du relationnel!
â Confondre les deux
-- Mettre un FK comme si c'était un PK
CREATE TABLE promos (
id UUID REFERENCES etudiants(id)
);
-- La promo référence un étudiant??
-- C'est l'inverse!
â Bien distinguer
-- PK = identifie CETTE table
-- FK = référence UNE AUTRE table
CREATE TABLE etudiants (
id UUID PRIMARY KEY, -- PK
promo_id UUID REFERENCES promos(id) -- FK
);
đĄ PK = "Qui suis-je?" â FK = "Qui est mon parent?"
â Sans NOT NULL
CREATE TABLE etudiants (
id UUID PRIMARY KEY,
nom VARCHAR(100),
email VARCHAR(255)
);
-- On peut insérer sans nom!
-- INSERT INTO etudiants(id) VALUES(...)
â Avec NOT NULL
CREATE TABLE etudiants (
id UUID PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL
);
-- La BDD refuse un insert sans nom!
â ïž Demandez-vous toujours : "Cette information est-elle obligatoire?" Si oui â NOT NULL
â FK cĂŽtĂ© 1
CREATE TABLE promos (
id UUID PRIMARY KEY,
nom VARCHAR(50),
etudiant_id UUID REFERENCES etudiants(id)
);
-- Une promo a PLUSIEURS étudiants!
-- On ne peut stocker qu'un seul id
â FK cĂŽtĂ© N
CREATE TABLE etudiants (
id UUID PRIMARY KEY,
nom VARCHAR(100),
promo_id UUID REFERENCES promos(id)
);
-- Chaque étudiant a UNE promo
-- Plusieurs Ă©tudiants â mĂȘme promo_id
đĄ RĂšgle d'or : dans une relation 1-N, la FK va toujours du cĂŽtĂ© N (le "plusieurs")
â Utiliser auto-increment pour les PK
Devinalbe, collisions quand on merge des bases â prĂ©fĂ©rer UUID
â InsĂ©rer dans la table enfant avant le parent
La FK rejette : le parent doit exister d'abord!
â Oublier la table de liaison pour N-N
On ne peut pas mettre un tableau dans une colonne SQL!
â Ne pas tester ses requĂȘtes dans psql
Toujours valider en console avant de coder!
đșïž
Map = Table
La clé = PK, l'objet = la ligne
đ
FK = Intégrité
Pas de données orphelines
đ
1-N : FK cÎté N
La relation la plus courante
đ
UUID > Auto-increment
Unique, non devinable, pas de collision
1. Installer PostgreSQL et se connecter avec psql
Créer une base bootcode et un utilisateur student
2. Créer les tables promos et etudiants
Avec UUID, NOT NULL, et la FK promo_id dans etudiants
3. Insérer 2 promos et 5 étudiants
Utiliser INSERT INTO avec les bons types de données
4. Lister les étudiants avec leur promo (JOIN)
SELECT avec JOIN pour voir la relation en action
Bonus : Créer une table cours + table de liaison N-N
etudiant_cours avec deux FK et PRIMARY KEY composée
Les BDD relationnelles sont le fondement du web moderne
Prochaine leçon : RequĂȘtes avancĂ©es â JOIN, WHERE, ORDER BY, agrĂ©gats