Les vues – classiques et matérialisées
Bonne lecture et bon apprentissage !
Junior TSAFACK – 20/08/2026
⏱️ Temps de lecture estimé : 9 minutes
Après avoir exploré les index qui améliorent les performances des requêtes, nous abordons maintenant un outil tout aussi puissant : les vues. Les vues permettent de simplifier l’accès aux données, de masquer la complexité des requêtes et de gérer finement les droits d’accès. PostgreSQL propose deux types de vues : les vues classiques (virtuelles) et les vues matérialisées (physiques). Ce cours vous présente ces deux concepts et vous aide à choisir la bonne solution selon vos besoins.
Qu’est-ce qu’une vue ?
Section titled “Qu’est-ce qu’une vue ?”Une vue (ou view) est une requête SQL sauvegardée dans la base de données. Elle se comporte comme une table virtuelle : vous pouvez l’interroger avec SELECT, et même, dans certains cas, effectuer des mises à jour.
Intérêts des vues
Section titled “Intérêts des vues”| Bénéfice | Description |
|---|---|
| Simplification | Évitez de réécrire des requêtes complexes (jointures, agrégations) à chaque fois. |
| Abstraction | Masquez la structure réelle des tables (normalisation, jointures multiples). |
| Sécurité | Limitez l’accès à certaines colonnes ou lignes (masquage de données). |
| Réutilisabilité | Une vue peut être utilisée dans d’autres vues ou requêtes. |
| Évolution | Modifiez la vue sans changer les applications qui l’utilisent. |
1. Les vues classiques
Section titled “1. Les vues classiques”Principe
Section titled “Principe”Une vue classique (aussi appelée vue virtuelle) est une requête stockée. Elle ne contient pas de données physiques : chaque fois que vous l’interrogez, PostgreSQL exécute la requête qui la définit.
Création d’une vue classique
Section titled “Création d’une vue classique”CREATE VIEW nom_vue ASSELECT colonnesFROM tables[WHERE condition][WITH CHECK OPTION];Exemple pratique
Section titled “Exemple pratique”Créons une table de produits et une vue qui simplifie l’accès aux produits en stock.
-- Table des produitsCREATE TABLE produits ( id SERIAL PRIMARY KEY, nom VARCHAR(100) NOT NULL, prix NUMERIC(10,2) NOT NULL, stock INTEGER NOT NULL DEFAULT 0, categorie VARCHAR(50));
-- Insertion de donnéesINSERT INTO produits (nom, prix, stock, categorie) VALUES ('Ordinateur portable', 899.99, 15, 'Informatique'), ('Souris sans fil', 29.99, 50, 'Informatique'), ('Clavier mécanique', 79.99, 30, 'Informatique'), ('Écran 27 pouces', 299.99, 8, 'Informatique'), ('Table de bureau', 149.99, 5, 'Mobilier'), ('Chaise ergonomique', 199.99, 12, 'Mobilier');
-- Créer une vue des produits en stock (stock > 0)CREATE VIEW produits_disponibles ASSELECT id, nom, prix, stock, categorieFROM produitsWHERE stock > 0;
-- Interroger la vueSELECT * FROM produits_disponibles;Résultat (tous les produits sauf ceux à stock 0) :
| id | nom | prix | stock | categorie |
|---|---|---|---|---|
| 1 | Ordinateur portable | 899.99 | 15 | Informatique |
| 2 | Souris sans fil | 29.99 | 50 | Informatique |
| 3 | Clavier mécanique | 79.99 | 30 | Informatique |
| 4 | Écran 27 pouces | 299.99 | 8 | Informatique |
| 5 | Table de bureau | 149.99 | 5 | Mobilier |
| 6 | Chaise ergonomique | 199.99 | 12 | Mobilier |
Avantages des vues classiques
Section titled “Avantages des vues classiques”- Zéro stockage : aucune donnée dupliquée.
- Toujours à jour : la vue reflète en temps réel l’état des tables.
- Facile à créer et modifier.
Inconvénients des vues classiques
Section titled “Inconvénients des vues classiques”- Performance : chaque accès exécute la requête (coût potentiel élevé).
- Pas d’index : impossible d’indexer directement une vue (mais on peut indexer les tables sous-jacentes).
Vues avec jointures
Section titled “Vues avec jointures”Les vues brillent particulièrement lorsqu’elles encapsulent des jointures complexes.
Exemple : vue avec jointure
Section titled “Exemple : vue avec jointure”-- Table des catégoriesCREATE TABLE categories ( id SERIAL PRIMARY KEY, nom VARCHAR(50) NOT NULL);
INSERT INTO categories (nom) VALUES ('Informatique'), ('Mobilier'), ('Électroménager');
-- Ajout de la clé étrangère à produitsALTER TABLE produits ADD COLUMN categorie_id INTEGER REFERENCES categories(id);
-- Mise à jour des donnéesUPDATE produits SET categorie_id = 1 WHERE categorie = 'Informatique';UPDATE produits SET categorie_id = 2 WHERE categorie = 'Mobilier';ALTER TABLE produits DROP COLUMN categorie;
-- Créer une vue qui joint produits et categoriesCREATE VIEW produits_detail ASSELECT p.id, p.nom AS produit, p.prix, p.stock, c.nom AS categorieFROM produits pINNER JOIN categories c ON p.categorie_id = c.id;
-- Interroger la vueSELECT * FROM produits_detail;Résultat :
| id | produit | prix | stock | categorie |
|---|---|---|---|---|
| 1 | Ordinateur portable | 899.99 | 15 | Informatique |
| 2 | Souris sans fil | 29.99 | 50 | Informatique |
| … | … | … | … | … |
💡 Bon à savoir : Les vues peuvent utiliser des fonctions, des sous-requêtes, des
UNION, et même des requêtes récursives (WITH RECURSIVE).
Mise à jour via une vue (règle de mise à jour)
Section titled “Mise à jour via une vue (règle de mise à jour)”Les vues classiques sont généralement en lecture seule. Cependant, PostgreSQL permet de mettre à jour les tables sous-jacentes via une vue si certaines conditions sont remplies :
- La vue porte sur une seule table (pas de jointure, pas de sous-requête, pas de fonction d’agrégation).
- La vue n’utilise pas
DISTINCT,GROUP BY,HAVING,UNION, etc. - La vue inclut toutes les colonnes obligatoires (ex :
NOT NULLsans défaut).
Exemple de mise à jour via une vue
Section titled “Exemple de mise à jour via une vue”-- Vue simple sur une tableCREATE VIEW produits_view ASSELECT id, nom, prix, stock FROM produits;
-- Mise à jour réussieUPDATE produits_view SET prix = 899.99 WHERE id = 1;UPDATE produits_view SET stock = stock + 5 WHERE id = 2;INSERT INTO produits_view (nom, prix, stock, categorie_id)VALUES ('Tablette', 399.99, 20, 1);
-- VérificationSELECT * FROM produits_view;⚠️ Attention : Les mises à jour via une vue ne sont pas toujours possibles. Pour les vues complexes, utilisez des déclencheurs (
INSTEAD OFtriggers) pour personnaliser les mises à jour.
Les vues matérialisées
Section titled “Les vues matérialisées”Principe
Section titled “Principe”Une vue matérialisée (ou materialized view) est une vue qui stocke physiquement les données sur le disque. Contrairement à une vue classique, les données sont figées au moment de la création ou d’un rafraîchissement.
Création d’une vue matérialisée
Section titled “Création d’une vue matérialisée”CREATE MATERIALIZED VIEW nom_vue ASSELECT colonnesFROM tables[WHERE condition];Exemple pratique
Section titled “Exemple pratique”-- Créer une vue matérialisée des produits les plus vendusCREATE MATERIALIZED VIEW produits_populaires ASSELECT p.id, p.nom, p.prix, COUNT(c.id) AS nb_commandesFROM produits pLEFT JOIN commandes c ON c.produit_id = p.idGROUP BY p.id, p.nom, p.prixHAVING COUNT(c.id) > 10;
-- Interroger la vue matérialiséeSELECT * FROM produits_populaires;Avantages des vues matérialisées
Section titled “Avantages des vues matérialisées”- Performance : les données sont précalculées et stockées.
- Possibilité d’index : vous pouvez créer des index sur la vue matérialisée.
- Réduction de charge : les requêtes complexes ne sont pas réexécutées à chaque accès.
Inconvénients des vues matérialisées
Section titled “Inconvénients des vues matérialisées”- Données figées : la vue n’est pas automatiquement mise à jour quand les tables sources changent.
- Maintenance : il faut périodiquement rafraîchir la vue avec
REFRESH MATERIALIZED VIEW. - Espace disque : les données sont dupliquées.
Rafraîchir une vue matérialisée
Section titled “Rafraîchir une vue matérialisée”-- Rafraîchir la vue (bloque les lectures pendant l'opération)REFRESH MATERIALIZED VIEW produits_populaires;
-- Rafraîchir sans bloquer les lectures (CONCURRENTLY) - nécessite un index uniqueREFRESH MATERIALIZED VIEW CONCURRENTLY produits_populaires;⚠️ Bon à savoir : Pour utiliser
REFRESH CONCURRENTLY, vous devez d’abord créer un index unique sur la vue matérialisée.
Index sur une vue matérialisée
Section titled “Index sur une vue matérialisée”-- Créer un index pour accélérer les recherchesCREATE INDEX idx_produits_populaires_nom ON produits_populaires (nom);
-- Créer un index unique pour permettre le REFRESH CONCURRENTLYCREATE UNIQUE INDEX idx_produits_populaires_id ON produits_populaires (id);Cas d’usage typiques
Section titled “Cas d’usage typiques”1. Vue pour simplifier les requêtes
Section titled “1. Vue pour simplifier les requêtes”-- Vue des commandes avec détails client et produitCREATE VIEW commandes_detail ASSELECT c.id AS commande_id, cl.nom AS client, cl.email AS client_email, p.nom AS produit, p.prix, c.quantite, c.montant_total, c.date_commandeFROM commandes cJOIN clients cl ON c.client_id = cl.idJOIN produits p ON c.produit_id = p.id;2. Vue pour la sécurité (masquage de colonnes)
Section titled “2. Vue pour la sécurité (masquage de colonnes)”-- Vue qui masque les colonnes sensibles (salaire, numéro de sécurité sociale)CREATE VIEW employes_public ASSELECT id, nom, prenom, email, serviceFROM employes;-- Les colonnes 'salaire' et 'ssn' ne sont pas exposées3. Vue matérialisée pour un rapport (BI)
Section titled “3. Vue matérialisée pour un rapport (BI)”-- Rapport mensuel des ventesCREATE MATERIALIZED VIEW rapport_ventes_mensuel ASSELECT DATE_TRUNC('month', date_commande) AS mois, c.nom AS categorie, SUM(ca.quantite) AS total_quantite, SUM(ca.montant_total) AS chiffre_affairesFROM commandes caJOIN produits p ON ca.produit_id = p.idJOIN categories c ON p.categorie_id = c.idGROUP BY mois, c.nomORDER BY mois DESC;
-- Rafraîchir chaque nuitREFRESH MATERIALIZED VIEW rapport_ventes_mensuel;Bonnes pratiques
Section titled “Bonnes pratiques”| Cas | Recommandation |
|---|---|
| Requête simple, données fréquemment mises à jour | Utilisez une vue classique. |
| Requête complexe, données figées dans le temps | Utilisez une vue matérialisée. |
| Besoin de masquer des colonnes sensibles | Utilisez une vue classique. |
| Rapports BI avec données agrégées | Utilisez une vue matérialisée (rafraîchissement périodique). |
| Mise à jour via une vue | Utilisez une vue classique simple (sans jointure). |
| Index nécessaire sur la vue | Utilisez une vue matérialisée (les vues classiques ne peuvent pas être indexées directement). |
Tableau récapitulatif
Section titled “Tableau récapitulatif”| Caractéristique | Vue classique | Vue matérialisée |
|---|---|---|
| Stockage des données | Non (virtuelle) | Oui (physique) |
| Toujours à jour | Oui | Non (nécessite rafraîchissement) |
| Performance | Variable (exécute la requête) | Excellente (données précalculées) |
| Indexation possible | Non (mais les tables sous-jacentes peuvent être indexées) | Oui |
| Mise à jour possible | Oui (si conditions remplies) | Non (directement) |
| Espace disque | Aucun | Occupe de l’espace |
| Rafraîchissement | Automatique | Manuel (REFRESH) |
Commandes récapitulatives
Section titled “Commandes récapitulatives”| Action | Commande |
|---|---|
| Créer une vue classique | CREATE VIEW nom AS SELECT ...; |
| Modifier une vue | CREATE OR REPLACE VIEW nom AS SELECT ...; |
| Supprimer une vue | DROP VIEW nom; |
| Créer une vue matérialisée | CREATE MATERIALIZED VIEW nom AS SELECT ...; |
| Rafraîchir une vue matérialisée | REFRESH MATERIALIZED VIEW nom; |
| Rafraîchir sans bloquer | REFRESH MATERIALIZED VIEW CONCURRENTLY nom; |
| Supprimer une vue matérialisée | DROP MATERIALIZED VIEW nom; |
| Lister les vues | \dv ou \dv+ |
| Voir la définition d’une vue | SELECT pg_get_viewdef('nom_vue'::regclass); |
Prochain chapitre
Section titled “Prochain chapitre”Vous savez maintenant créer et utiliser des vues classiques et matérialisées pour simplifier vos requêtes, améliorer les performances et gérer les droits. Dans le prochain cours, nous aborderons la gestion des utilisateurs et des rôles, un élément fondamental pour sécuriser votre base de données.
👉 Cours 8 : Utilisateurs et rôles
Junior TSAFACK – 20/08/2026