Introduction aux BDD Relationnelles

Tables, Clés, Relations et SQL

Bootcode IWA-S04 — Semaine 14, Jour 1

Objectifs de la leçon

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

Plan du cours

1

Le problÚme du stockage en mémoire

Tout disparaßt au redémarrage

2

Qu'est-ce qu'une BDD relationnelle ?

Tables, colonnes, lignes

3

Vocabulaire

Clé primaire, clé étrangÚre, types de colonnes

4

Les 3 types de relations

1-1, 1-N, N-N

5

Installation de PostgreSQL

Premiers pas avec psql

Module 1

Le problÚme du stockage en mémoire

Tout disparaßt au redémarrage

Vos données vivent... en RAM

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

PremiÚre idée : sauvegarder dans un fichier

// 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 :

  • ‱ Pas de recherche rapide (il faut tout lire)
  • ‱ Concurrency : 2 utilisateurs qui Ă©crivent en mĂȘme temps
  • ‱ Pas de validation automatique des donnĂ©es
  • ‱ Pas de relations entre entitĂ©s

La solution : une base de données

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

Qu'est-ce qu'une BDD relationnelle ?

Tables, colonnes, lignes

Le modĂšle relationnel

InventĂ© par Edgar Codd en 1970 — organiser les donnĂ©es en tables liĂ©es par des relations

Table = une entité

etudiants
id
nom
age
1
Alice
20
2
Bob
22

Table

Comme un onglet Excel

Colonne (champ)

Le type d'information (nom, age...)

Ligne (enregistrement)

Une entrée complÚte (Alice, 20)

Anatomie d'une table

📋 etudiants
🔑 id (PK)
nom
email
promo_id (FK)
1
Alice
1
2
Bob
1
3
Charlie
2

🔑 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

Analogie : Map → 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

Vocabulaire essentiel

Clé primaire, clé étrangÚre, types de colonnes

🔑 La clĂ© primaire (Primary Key)

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

🔗 La clĂ© Ă©trangĂšre (Foreign Key)

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

Les types de colonnes essentiels

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 : protéger vos données

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

Les 3 types de relations

1-1, 1-N, N-N

Relation 1-1 (Un Ă  Un)

Un enregistrement A est lié à exactement un enregistrement B

utilisateurs
id (PK)
nom
1
Alice
2
Bob
profils
id (PK)
bio
user_id (FK)
1
Dev JS
1
2
Dev PHP
2

// 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Ă©)

Relation 1-N (Un à Plusieurs) — la plus courante!

Un enregistrement A est lié à plusieurs enregistrements B

Exemple : une promo a plusieurs étudiants

promos
id (PK)
nom
1
IWA-S04
2
IWA-S05
etudiants
id (PK)
nom
promo_id (FK)
1
Alice
1
2
Bob
1
3
Charlie
2

⚡ 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

Relation N-N (Plusieurs Ă  Plusieurs)

Plusieurs A sont liĂ©s Ă  plusieurs B — nĂ©cessite une table de liaison

etudiants
id (PK)
nom
1
Alice
2
Bob
etudiant_cours (table de liaison)
etudiant_id (FK)
cours_id (FK)
1
1
1
2
2
1
cours
id (PK)
titre
1
SQL
2
React

// 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

Installation de PostgreSQL

Premiers pas avec psql

Installer PostgreSQL

⚠ 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

Premiers pas avec psql

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;

CREATE TABLE avec contraintes

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()

);

INSERT INTO — InsĂ©rer des donnĂ©es

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]', ...);

SELECT — Lire des donnĂ©es

-- 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!

❌ vs ✅ ClĂ© primaire vs ClĂ© Ă©trangĂšre

❌ 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?"

❌ vs ✅ Oublier NOT NULL

❌ 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

❌ vs ✅ OĂč mettre la clĂ© Ă©trangĂšre?

❌ 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")

⚠ Autres piĂšges Ă  Ă©viter

❌ 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!

À retenir!

đŸ—ș

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

Exercices pratiques

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

Questions?

Les BDD relationnelles sont le fondement du web moderne

Prochaine leçon : RequĂȘtes avancĂ©es — JOIN, WHERE, ORDER BY, agrĂ©gats