Chapitre 199 minDébutant
SQL ou NoSQL ?
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- distinguer les grandes familles de bases de données ;
- choisir entre une base relationnelle et une base orientée documents ;
- interroger une colonne JSON dans MySQL ;
- expliquer le théorème CAP.
3 exercices corrigés
SQL ou NoSQL ? Une base relationnelle range ses données dans des tables liées par des clés et s'interroge en SQL. Les bases NoSQL suivent d'autres modèles : clé-valeur, documents, colonnes larges, graphes. Ce chapitre t'aide à choisir, compare un ticket de la base d'exemple parc à un document MongoDB et montre les colonnes JSON de MySQL.
Les familles de bases de données
Le modèle relationnel n'est pas le seul. Depuis les années 2000, d'autres familles, regroupées sous le nom NoSQL (not only SQL), répondent à des besoins particuliers.
| Famille | Principe | Exemples | Usage typique |
|---|---|---|---|
| Relationnelle | Tables, clés, jointures, transactions ACID | MySQL, MariaDB, PostgreSQL, SQL Server | Données structurées et liées : gestion, facturation, parc |
| Clé-valeur | Une clé donne une valeur, sans structure imposée | Redis, Memcached | Cache, sessions, compteurs, files d'attente |
| Document | Des documents JSON imbriqués, de structure variable | MongoDB, CouchDB | Catalogues, contenus, données au format variable |
| Colonnes larges | Des lignes aux colonnes très nombreuses, réparties sur de nombreux serveurs | Cassandra, HBase | Très gros volumes d'écritures, journaux, capteurs |
| Graphe | Des nœuds reliés par des relations | Neo4j | Réseaux sociaux, recommandations, dépendances |
| Séries temporelles | Des mesures horodatées | InfluxDB, Prometheus | Supervision, métriques, objets connectés |
Quand choisir une base orientée documents
Dans MongoDB, un ticket et ses interventions pourraient tenir dans un seul document :
{
"_id": 9,
"titre": "Rançongiciel suspecté",
"priorite": "critique",
"statut": "resolu",
"demandeur": { "id": 7, "nom": "Faure", "service": "Logistique" },
"interventions": [
{ "technicien": "Mercier", "date": "2026-10-05T08:20:00", "duree_min": 240 },
{ "technicien": "Diallo", "date": "2026-10-05T13:30:00", "duree_min": 180 },
{ "technicien": "Lambert", "date": "2026-10-06T09:00:00", "duree_min": 150 }
]
}
Lire le ticket complet ne demande plus aucune jointure, et un ticket peut porter des champs qu'un autre n'a pas. En contrepartie, le nom du service est recopié dans chaque ticket : si la Logistique change de nom, tous ses documents sont à modifier, et rien ne garantit que demandeur.id correspond à un employé existant. On retrouve les anomalies du tableur.
Un modèle document convient quand les données sont lues comme un tout, avec une structure qui varie, et peu de liens entre entités. Un modèle relationnel convient quand les données sont fortement liées, partagées entre plusieurs usages, et que leur cohérence compte. Pour un parc et un helpdesk, le relationnel reste le bon choix. Le cours MongoDB et API Node.js montre MongoDB en pratique.
Les colonnes JSON dans MySQL
MySQL offre un compromis : le type JSON stocke un document validé dans une colonne d'une table relationnelle. Les caractéristiques techniques varient d'un modèle de poste à l'autre ; plutôt que d'ajouter une colonne par caractéristique, on les range dans un document :
ALTER TABLE poste ADD COLUMN caracteristiques JSON;
UPDATE poste
SET caracteristiques = '{"ram_go": 16, "ssd_go": 512, "ecran_pouces": 14}'
WHERE id_poste = 12;
UPDATE poste
SET caracteristiques = JSON_OBJECT('ram_go', 8, 'ssd_go', 256)
WHERE id_poste = 7;
SELECT num_inventaire,
caracteristiques->>'$.ram_go' AS ram_go,
JSON_EXTRACT(caracteristiques, '$.ssd_go') AS ssd_go
FROM poste
WHERE caracteristiques->'$.ram_go' >= 16;
| num_inventaire | ram_go | ssd_go |
|---|---|---|
| PC-0012 | 16 | 512 |
-> extrait une valeur JSON, ->> l'extrait et retire les guillemets d'une chaîne. Un JSON invalide est refusé à l'insertion. Garde les colonnes JSON pour des attributs secondaires et variables : ce qui sert à joindre, à filtrer souvent ou à contraindre mérite une vraie colonne.
Cohérence et disponibilité : le théorème CAP
Quand une base est répartie sur plusieurs serveurs, une coupure réseau peut les séparer. Le théorème CAP dit qu'en cas de partition réseau (P), un système doit choisir entre la cohérence (C : tous les nœuds renvoient la même donnée, quitte à refuser de répondre) et la disponibilité (A : chaque nœud répond, quitte à renvoyer une donnée pas encore à jour).
Un SGBD relationnel en réplication synchrone privilégie la cohérence ; beaucoup de bases NoSQL réparties, comme Cassandra, privilégient la disponibilité et parlent de cohérence à terme (eventual consistency) : les nœuds finissent par converger. Pour un solde bancaire ou un stock de licences, on veut la cohérence ; pour le compteur de vues d'une vidéo, une valeur légèrement en retard est acceptable.
Exercices
Exercice 1 sur 3 Choisir un modèle Réussi À revoir
Pour chaque besoin, propose une famille de base de données et justifie en une phrase : (1) les sessions des utilisateurs d'un site web, (2) la facturation d'une ESN, (3) les relevés de température de 2 000 capteurs toutes les 10 secondes, (4) un catalogue de produits aux caractéristiques très variables.
Voir la réponseMasquer la réponse de l'exercice 1
- Clé-valeur (Redis) : on retrouve une session par sa clé, très vite, avec une expiration automatique.
- Relationnelle : des clients, des factures, des lignes, des paiements fortement liés, et une cohérence indispensable (transactions ACID).
- Séries temporelles (InfluxDB, ou PostgreSQL avec une extension dédiée) : des mesures horodatées, écrites en continu, interrogées par périodes.
- Document (MongoDB) ou une base relationnelle avec une colonne JSON : la structure varie d'un produit à l'autre.
Tu avais trouvé ?
Exercice 2 sur 3 Interroger une colonne JSON Réussi À revoir
Après les deux UPDATE de la section sur les colonnes JSON, affiche le numéro d'inventaire et la taille du SSD des postes qui ont une colonne caracteristiques renseignée, du plus gros SSD au plus petit.
Voir la réponseMasquer la réponse de l'exercice 2
SELECT num_inventaire, caracteristiques->>'$.ssd_go' AS ssd_go
FROM poste
WHERE caracteristiques IS NOT NULL
ORDER BY CAST(caracteristiques->>'$.ssd_go' AS UNSIGNED) DESC;
| num_inventaire | ssd_go |
|---|---|
| PC-0012 | 512 |
| PC-0007 | 256 |
->> renvoie du texte : sans le CAST, le tri serait alphabétique, et '1024' passerait avant '256'.
Tu avais trouvé ?
Exercice 3 sur 3 Du relationnel au document Réussi À revoir
Avec les fonctions JSON_OBJECT et JSON_ARRAYAGG de MySQL, écris la requête qui produit, pour le ticket 9, un seul document JSON contenant son numéro, son titre, le nom du demandeur et la liste de ses interventions (nom du technicien et durée de chacune). Quelle information du document MongoDB du ticket 9 cette requête recalcule-t-elle à chaque fois ?
Voir la réponseMasquer la réponse de l'exercice 3
SELECT JSON_OBJECT(
'id', t.id_ticket,
'titre', t.titre,
'demandeur', dem.nom,
'interventions', JSON_ARRAYAGG(
JSON_OBJECT('technicien', tech.nom, 'duree_min', i.duree_min))
) AS document
FROM ticket t
JOIN employe dem ON dem.id_employe = t.id_demandeur
JOIN intervention i ON i.id_ticket = t.id_ticket
JOIN employe tech ON tech.id_employe = i.id_technicien
WHERE t.id_ticket = 9
GROUP BY t.id_ticket, t.titre, dem.nom;
La requête renvoie une ligne : un document qui contient les trois interventions (Mercier 240, Diallo 180, Lambert 150). MySQL ne garantit ni l'ordre des clés d'un objet JSON, ni celui des éléments agrégés par JSON_ARRAYAGG.
Les noms du demandeur et des techniciens sont lus dans employe au moment de la requête : ils sont toujours à jour. Le document MongoDB, lui, les recopie : c'est plus rapide à lire, mais il faut les mettre à jour partout quand ils changent. Une API peut ainsi servir des documents JSON tout en gardant une base relationnelle cohérente.
Tu avais trouvé ?