Le choix du moteur de base de données est l'une des décisions d'architecture qui a le plus d'impact à long terme sur un système d'entreprise. Il conditionne le modèle de données, la stratégie de montée en charge, les coûts d'exploitation et jusqu'à la vitesse à laquelle l'équipe peut livrer de nouvelles fonctionnalités. Le débat entre SQL et NoSQL ne se résout pas en choisissant un camp : il se résout en comprenant quelles garanties offre chaque famille et ce qu'exige réellement la charge de travail. Dans ce guide, nous parcourons la modélisation relationnelle, la normalisation, les modèles de cohérence et les critères pratiques pour faire le bon choix en production.
Modèle relationnel : le standard SQL et les garanties ACID
Les bases de données relationnelles organisent l'information en tables (relations) composées de lignes et de colonnes aux types définis. Leur langage, SQL, est normalisé par la norme ISO/IEC 9075, ce qui garantit une syntaxe déclarative portable entre des moteurs comme PostgreSQL, MySQL/MariaDB, Oracle Database ou SQL Server. La force différenciatrice du modèle relationnel réside dans les propriétés ACID : Atomicité (une transaction s'applique entièrement ou pas du tout), Cohérence (les contraintes d'intégrité sont toujours respectées), Isolation (les transactions concurrentes ne s'interfèrent pas) et Durabilité (ce qui est validé survit à une panne).
L'isolation se matérialise par des niveaux définis par le standard : READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ et SERIALIZABLE. Chaque niveau est un compromis entre concurrence et anomalies tolérées (lectures sales, non reproductibles ou fantômes). PostgreSQL, par exemple, utilise le contrôle de concurrence multiversion (MVCC) pour que les lectures ne bloquent pas les écritures. Comprendre ces niveaux est ce qui distingue un système qui passe à l'échelle d'un système qui se dégrade sous charge à coups de verrous et d'interblocages (deadlocks).
Normalisation : de la théorie de Codd à la pratique
La normalisation, formalisée par Edgar F. Codd, vise à éliminer la redondance et les anomalies de mise à jour en décomposant les relations en formes normales successives :
- 1FN (Première Forme Normale) : chaque cellule contient une valeur atomique ; pas de listes à l'intérieur d'un même champ.
- 2FN : par-dessus la 1FN, tout attribut non clé dépend de la totalité de la clé primaire (pertinent pour les clés composées).
- 3FN : on élimine les dépendances transitives ; un attribut non clé ne doit pas dépendre d'un autre attribut non clé.
- BCNF (Boyce-Codd) : version plus stricte de la 3FN pour les cas avec plusieurs clés candidates qui se chevauchent.
En pratique, la plupart des schémas transactionnels (OLTP) sont conçus en 3FN ou BCNF pour garantir l'intégrité. Cependant, en analytique (OLAP) et en reporting, on applique une dénormalisation contrôlée — schémas en étoile ou en flocon de neige — car les lectures massives pénalisent les JOIN répétés. La règle opérationnelle : normalisez pour écrire, dénormalisez avec discernement pour lire, et mesurez toujours avec des données réelles avant d'optimiser.
NoSQL : quand le modèle relationnel gêne
NoSQL n'est pas une technologie unique, mais une famille de moteurs qui renoncent à une partie du modèle relationnel pour gagner en flexibilité de schéma ou en montée en charge horizontale. Ils se regroupent en quatre grandes catégories :
- Documentaires (MongoDB, Couchbase) : ils stockent des documents JSON/BSON imbriqués. Idéaux lorsque la structure de la donnée varie d'un enregistrement à l'autre ou évolue rapidement.
- Clé-valeur (Redis, DynamoDB) : accès par clé avec des latences de l'ordre de la microseconde ; parfaits pour le cache, les sessions et les compteurs.
- Colonnes à familles larges (Apache Cassandra, HBase) : écriture massive distribuée et séries temporelles à grande échelle.
- Orientés graphes (Neo4j, Amazon Neptune) : les relations comme citoyens de première classe ; recommandation, détection de fraude et réseaux sociaux.
Le fondement théorique qui justifie ces renoncements est le théorème CAP (Eric Brewer) : face à une partition réseau (P), un système distribué doit choisir entre Cohérence (C) et Disponibilité (A). De nombreux systèmes NoSQL adoptent le modèle BASE (Basically Available, Soft state, Eventually consistent), en privilégiant la disponibilité et en acceptant une cohérence à terme. Ce n'est pas « pire » qu'ACID : c'est une décision délibérée pour des charges où une réplique désynchronisée de quelques millisecondes est tolérable, mais où une coupure du service ne l'est pas.
Scalabilité : verticale, horizontale et sharding
La montée en charge verticale (ajouter du CPU, de la RAM ou du disque à un serveur) est simple, mais se heurte à un plafond physique et de coût. La montée en charge horizontale (répartir la charge entre plusieurs nœuds) est la voie naturelle de NoSQL et, de plus en plus, de SQL aussi par le partitionnement. Les techniques clés :
- Réplicas de lecture : des copies qui absorbent les requêtes en lecture seule, déchargeant le primaire dédié à l'écriture.
- Sharding : partition horizontale des données selon une clé (par exemple,
id_client % Nou par plage géographique). Chaque fragment vit sur un nœud distinct. - Bases distribuées NewSQL (CockroachDB, Google Spanner, YugabyteDB) : elles combinent montée en charge horizontale, garanties ACID et SQL standard, comblant l'écart historique.
L'erreur la plus coûteuse en sharding est de mal choisir la clé de partition : une clé à faible cardinalité ou biaisée crée des « points chauds » qui saturent un nœud pendant que les autres restent inactifs. Une bonne clé répartit la charge de façon uniforme et regroupe les données consultées ensemble, en évitant les requêtes qui doivent s'éventer sur tous les nœuds du cluster.
Indexation et optimisation des requêtes
L'index est la structure qui évite de parcourir toute la table pour trouver une ligne. Le plus courant est l'arbre B+ (B-tree), efficace pour les égalités et les plages ; les index hash ne servent que pour les égalités exactes ; les GIN/GiST de PostgreSQL indexent le JSON, le texte intégral et les données géospatiales ; et les index inversés soutiennent la recherche plein texte (full-text). Chaque index accélère certaines lectures, mais a un coût : il ralentit les écritures (il faut le maintenir à jour) et consomme de la mémoire et du disque. La discipline consiste à indexer les colonnes qui apparaissent fréquemment dans les clauses WHERE, JOIN et ORDER BY, et à supprimer les index que personne n'utilise.
L'outil de diagnostic fondamental est le plan d'exécution, que l'on obtient avec EXPLAIN ANALYZE sous PostgreSQL ou ses équivalents dans d'autres moteurs. Il révèle si le planificateur effectue un balayage séquentiel (sequential scan) coûteux ou utilise un index, si l'ordre des JOIN est optimal et où se concentre le temps. Anti-pratiques à éviter : appliquer des fonctions sur la colonne indexée dans le WHERE (cela annule l'index), utiliser SELECT * alors que seules trois colonnes sont nécessaires, et le classique problème N+1, dans lequel une application déclenche une requête par ligne d'un résultat au lieu d'une seule requête avec JOIN. Mesurer avant d'optimiser et mesurer de nouveau ensuite n'est pas optionnel : les intuitions sur les performances des bases de données sont souvent erronées.
Tableau comparatif : SQL face à NoSQL
| Critère | SQL (relationnel) | NoSQL |
|---|---|---|
| Schéma | Rigide et prédéfini | Flexible ou sans schéma |
| Cohérence | Forte (ACID) | À terme / ajustable (BASE) |
| Montée en charge | Verticale et partitionnement | Horizontale native |
| Requêtes complexes | JOIN et agrégations puissants | Limitées ; logique dans l'application |
| Cas idéal | Transactions, ERP, finance | Catalogues, IoT, cache, graphes |
Mise en œuvre : les étapes pour réussir
- Caractérisez la charge : ratio lecture/écriture, volume, latence cible et schémas d'accès.
- Définissez les garanties non négociables : avez-vous besoin de transactions multitables ? Tolérez-vous une cohérence à terme ?
- Modélisez d'abord les requêtes, pas les tables en NoSQL : l'accès dicte la conception.
- Indexez avec intention : chaque index accélère les lectures mais pénalise les écritures et occupe de la mémoire.
- Planifiez les sauvegardes et la reprise : définissez le RPO et le RTO, et testez les restaurations, pas seulement les sauvegardes.
- Protégez la donnée personnelle : chiffrement au repos et en transit, et minimisation conforme au RGPD.
Erreurs courantes qui coûtent cher
- Utiliser NoSQL « parce que c'est moderne » pour des données fortement relationnelles : on finit par réimplémenter les JOIN dans l'application.
- Dénormaliser prématurément en SQL sans mesurer, générant des anomalies de mise à jour.
- Ignorer le niveau d'isolation et subir des conditions de course (race conditions) en production.
- Ne pas définir de TTL ni de politique de rétention et laisser les tables croître sans contrôle.
- Traiter la base de données comme une boîte noire et ne pas surveiller les requêtes lentes avec
EXPLAIN.
Persistance polyglotte : le meilleur des deux mondes
L'architecture moderne est rarement monolithique dans sa couche de données. La persistance polyglotte consiste à utiliser le moteur adapté à chaque sous-domaine : PostgreSQL pour les commandes et la facturation, Redis pour les sessions et le cache, Elasticsearch pour la recherche plein texte et Cassandra pour la télémétrie. Le défi se déplace alors vers la cohérence entre les magasins de données, qui se résout par des patrons comme l'event sourcing, le CDC (Change Data Capture) ou le patron Outbox pour propager les changements de façon fiable.
Sécurité, conformité et gouvernance de la donnée
Une base de données d'entreprise est, presque toujours, le dépôt des actifs les plus sensibles de l'organisation, et donc la cible prioritaire de toute attaque. La protection se construit en couches. En matière de chiffrement, on distingue les données au repos (Transparent Data Encryption au niveau du fichier ou du tablespace) et les données en transit (TLS entre l'application et le moteur). En matière de contrôle d'accès, le principe du moindre privilège se matérialise par des rôles, des permissions granulaires par table ou par colonne et, dans les moteurs avancés, une sécurité au niveau de la ligne (RLS) qui filtre les enregistrements visibles par chaque utilisateur. L'audit enregistre qui a accédé à quoi et quand, exigence habituelle dans les secteurs réglementés.
Du point de vue du RGPD, la base de données est l'endroit où se concrétisent des principes comme la minimisation (ne pas stocker plus de données personnelles que nécessaire), la limitation de la durée de conservation (politiques de rétention et d'effacement automatique), et les droits de la personne concernée comme le droit à l'effacement, qui oblige à pouvoir localiser et supprimer de façon fiable tous les enregistrements d'une personne. La pseudonymisation et l'anonymisation sont des techniques recommandées pour réduire le risque, en particulier dans les environnements de développement et d'analytique qui ne doivent pas fonctionner avec des données personnelles réelles. La gouvernance de la donnée — catalogue, traçabilité (lignage), classification par sensibilité et propriétaire responsable — cesse d'être un luxe pour devenir une exigence de conformité et de qualité.
Questions fréquentes
NoSQL remplace-t-il les bases de données relationnelles ?
Non. Ce sont des outils complémentaires. Les bases relationnelles restent irremplaçables pour les transactions financières, les ERP et tout domaine où l'intégrité référentielle est non négociable. NoSQL brille par sa flexibilité de schéma et sa montée en charge horizontale.
Que signifie qu'un système soit « cohérent à terme » ?
Qu'après une écriture, les répliques convergent vers la même valeur en peu de temps, mais que, durant cet intervalle, une lecture peut renvoyer une donnée légèrement désynchronisée. C'est acceptable pour des catalogues ou des réseaux sociaux, pas pour des soldes bancaires.
Quand est-il pertinent de dénormaliser un schéma SQL ?
Lorsque les requêtes de lecture dominent, que les JOIN répétés constituent le goulet d'étranglement mesuré et que la fréquence d'écriture est faible. Toujours avec des données réelles de performance sur la table, jamais par intuition.
Qu'est-ce que NewSQL ?
Une génération de moteurs (CockroachDB, Spanner, YugabyteDB) qui offre du SQL standard et des garanties ACID avec une montée en charge horizontale distribuée, éliminant le dilemme classique entre cohérence forte et échelle.
Conclusion
Il n'existe pas de base de données universellement supérieure ; il existe la base de données adaptée à une charge de travail précise. La bonne question n'est pas « SQL ou NoSQL ? », mais « quelles garanties de cohérence, quel modèle de montée en charge et quel modèle d'accès exige ce domaine ? ». Un système de facturation réclame de l'ACID et un schéma normalisé en 3FN ; un catalogue de produits changeant apprécie un moteur documentaire ; une télémétrie de millions d'événements par minute demande un moteur en colonnes distribué. Chez Summum Sistemas, nous concevons chaque couche de persistance en partant des schémas d'accès réels et des exigences d'intégrité et de conformité, en évitant aussi bien le surdimensionnement que les décisions de mode. Réussir ici ne se remarque pas le premier mois : cela se remarque quand le système passe à l'échelle et que l'architecture tient sans réécritures.