Du latin integritas (« entier, intact, inaltéré »). Comprendre tous les mécanismes qui protègent les données à l'intérieur et autour de la base.
Pourquoi l'intégrité ?
La première loi de l'architecture logicielle : les applications passent, mais les données restent.
Au fil des décennies, l'interface d'un système sera réécrite en Java, en Web ou en mobile. Mais si la base de données perd sa cohérence, c'est la mémoire même de l'organisation qui s'effondre.
✅ Qu'est-ce qu'une donnée intègre ?
C'est une donnée exacte (sans erreur de domaine), cohérente (aucune référence vers un élément fantôme) et intacte (non altérée sur le disque ou le réseau).
🛡️ Pourquoi le code Java ne suffit-il pas ?
Si vos règles ne sont vérifiées que dans un formulaire applicatif, le premier script d'importation, bogue ou accès direct contournera vos validations. Le SGBD doit être le gardien ultime.
Les deux périmètres de défense
🛡️ I. Le périmètre INTERNE (au cœur du SGBD)
- 1. La structure (DDL) : typer chaque colonne et chaque table.
- 2. Les contraintes SQL : interdire doublons, valeurs nulles ou orphelins.
- 3 & 4. Déclencheurs & Procédures : réagir automatiquement aux écritures.
🌐 II. Le périmètre EXTERNE (le système et le temps)
- 5. La représentation : encodage UTF-8, casse et expressions régulières.
- 6, 7 & 8. La continuité : sauvegardes, migrations Git (
ALTER TABLE) et Checksum. - 9. Le pont applicatif : synchronisation d'objets via ORM.
Présentation des SUJETS
🛡️ Contraintes d'intégrité internes (SGBD)
- Data Definition Language (DDL)Sujet 1 →
- Contraintes d'intégrité (NOT NULL, PK, FK, CHECK)Sujet 2 →
- Déclencheurs (Triggers & CASCADE)Sujet 3 →
- Procédures stockées (PL/pgSQL, T-SQL)Sujet 4 →
🌐 Encodage, Administration externe & ORM
- Encodage & casse (UTF-8, ISO-8859-1, Regex)Sujet 5 →
- Sauvegarde & restauration (pg_dump à chaud)Sujet 6 →
- Versionnement des bases de données (Git + ALTER)Sujet 7 →
- Checksum & fingerprint (SHA-256, MD5)Sujet 8 →
- Object Relational Mapping (ORM : Hibernate, LINQ)Sujet 9 →
CONTRAINTES D'INTÉGRITÉ
INTERNES DE LA BASE DE DONNÉES
Première partie
Data Definition Language (DDL)
Le DDL est le langage SQL qui permet de créer/modifier/détruire des tables, des colonnes et des clés.
| Opération | Table | Colonne | Clés |
|---|---|---|---|
| Créer | CREATE TABLE matable (nomcolonne type, nomcolonne type); |
ALTER TABLE matable ADD colonne type; |
ALTER TABLE matable ADD PRIMARY KEY (unetelle); |
| Modifier | ALTER TABLE matable ... |
ALTER TABLE matable ALTER/MODIFY colonne type; |
|
| Détruire | DROP TABLE matable; |
ALTER TABLE matable DROP COLUMN colonne; |
ALTER TABLE matable DROP PRIMARY KEY; |
Contraintes d'intégrité
Les contraintes du SQL couvrent la majorité des besoins :
📌 Contraintes de colonnes
- NOT NULL - Empêche les valeurs d'être nulles dans cette colonne
- DEFAULT - Spécifie la valeur par défaut
- CHECK - Condition à respecter pour toutes les valeurs de la colonne
🔑 Contraintes de table
- UNIQUE - Oblige toutes les valeurs de la colonne à être différentes
- PRIMARY KEY - Valeur unique qui sert d'identifiant à chaque rangée
- FOREIGN KEY - Désigne toujours une rangée d'une autre table
- INDEX - La colonne sera indexée dans la mémoire pour l'accès rapide
Contraintes d'intégrité (Exemple)
Illustration en SQL : voici comment ces contraintes de colonnes et de table s'assemblent lors d'un CREATE TABLE :
CREATE TABLE produit (
id_produit SERIAL PRIMARY KEY,
code_sku VARCHAR(20) NOT NULL UNIQUE,
prix NUMERIC(8,2) NOT NULL CHECK (prix >= 0),
en_stock BOOLEAN DEFAULT TRUE,
id_categorie INT NOT NULL REFERENCES categorie(id_categorie)
);
CREATE INDEX idx_produit_categorie ON produit(id_categorie);
CHECK), tout SKU en double (UNIQUE) et toute référence vers une catégorie fantôme (FOREIGN KEY).
Déclencheurs (Triggers)
Les déclencheurs s'utilisent pour déclencher des ajustements au reste de la base de données lorsque des données sont modifiées. Le but est de maintenir l'intégrité.
🔗 Pour les contraintes d'intégrité
(la contrainte) ON INSERT / UPDATE / DELETE CASCADE / SET NULL / RESTRICT
⚡ Pour les procédures stockées
CREATE TRIGGER untel BEFORE / AFTER INSERT / UPDATE / DELETE
ON DELETE CASCADE répercute automatiquement une suppression sur les clés étrangères enfants, tandis que CREATE TRIGGER permet de lancer un traitement personnalisé (comme un journal d'audit).
Procédures stockées
Les procédures stockées sont de petits bouts de code qui sont programmés directement dans la base de données.
Certaines procédures non-nommées sont directement attachées à leur événement déclencheur (trigger) et ne peuvent être appelées d'un autre point d'exécution. Par exemple :
CREATE TRIGGER apres_ajout_jouet AFTER INSERT ON jouet BEGIN ... END;
Les procédures stockées nommées sont des fonctions nommées programmées à l'intérieur de la base de données. Leur syntaxe n'est pas standard, elle diffère d'un SGBD à l'autre. Leur utilisation était importante dans le passé mais de nos jours elle est réservée au maintien de l'intégrité.
Trigger & procédures stockées par SGBD
Chaque SGBD possède son propre dialecte procédural pour écrire ses déclencheurs et fonctions :
- POSTGRESQL (PL/pgSQL) :
docs.postgresql.fr/current/sql-createtrigger.html·docs.postgresql.fr/current/plpgsql-trigger.html - MYSQL :
dev.mysql.com/doc/refman/en/triggers.html(sauf la partie sur la logique métier / business logic) - SQL SERVER (T-SQL) :
learn.microsoft.com/sql/t-sql/statements/create-trigger-transact-sql
Nous y programmerons pas à pas en PostgreSQL / PL/pgSQL et dans pgAdmin 4 les séquences, les clés étrangères et la fonction déclencheur
journaliser() avec les variables NEW et OLD.
INTÉGRITÉ EXTERNE
ENCODAGE, ADMINISTRATION, GIT & ORM
Deuxième partie
Encodage et casse
- ISO 8859-1 (alphabet occidental 1 octet) versus UTF-8 (universel 1 à 4 octets) : lire de l'UTF-8 en ISO-8859-1 corrompt
MontréalenMontréal. - little-endian vs big-endian (ordre des octets en mémoire) · case-sensitive vs case-insensitive (
LIKEvsILIKE) · REGEX (expressions régulières).
-- Exemple PostgreSQL combinant UTF-8, insensibilité à la casse (~*) et Regex : ALTER TABLE client ADD CONSTRAINT format_code_postal CHECK (code_postal ~* '^[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]$');
Sauvegarde et restauration
📄 Exports SQL et imports SQL (à chaud)
Permet de sauvegarder sans interrompre le serveur (instantané cohérent) et de transférer des données entre serveurs ou versions.
💾 Fichiers binaires natifs sur disque (à froid)
Rapide mais limité au même SGBD et à la même version exacte (parfois des soucis d'index surviennent : solution de secours uniquement).
# Exporter à chaud en SQL (sauvegarde) et réimporter (restauration) : pg_dump -U postgres -d fermedelest -f sauvegarde_ferme.sql psql -U postgres -d fermedelest -f sauvegarde_ferme.sql
Versionnement de base de données
Chaque révision du logiciel dans Git doit inclure sa migration SQL correspondante DANS LE MÊME COMMIT. En production, on n'écrase jamais les tables avec DROP TABLE : on applique un différentiel ALTER TABLE.
ALTER TABLE client ADD COLUMN telephone VARCHAR(20) NOT NULL DEFAULT ''; git add src/dao/ClientDAO.java sql/migrations/2026_10_ajout_telephone.sql && git commit -m "Ajout téléphone (DAO + ALTER)"
Checksum et Fingerprint
- CHECKSUM : calcul mathématique sur les bits d'un fichier (somme, XOR, MD5, SHA-256) qui change radicalement si un seul bit est altéré lors d'un transfert ou sur disque.
- FINGERPRINT : généralisation de l'usage de checksums sur la partie constante d'un système (ex. fichiers de configuration du serveur qui ne doivent pas bouger entre deux interventions admin).
sha256sum sauvegarde_ferme.sql > sauvegarde_ferme.sql.sha256 sha256sum --check sauvegarde_ferme.sql.sha256 # Affiche : sauvegarde_ferme.sql: OK
Object Relational Mapping (ORM)
L'ORM semi-automatise la sauvegarde et la mise à jour des rangées de tables correspondant à des objets en mémoire vive (chaque rangée = un objet métier). Frameworks célèbres : Hibernate (Java), LINQ / Entity Framework (.NET) et Doctrine (PHP).