Retour au cours

data / sql

Vues

Leçon 131 exercice

Explication

Ce que vous allez apprendre

  • Créer une vue pour nommer et réutiliser une requête complexe
  • Comprendre pourquoi une vue classique ne stocke aucune donnée propre
  • Créer et rafraîchir une vue matérialisée pour accélérer une lecture répétée
  • Utiliser une vue pour restreindre l'accès à certaines colonnes sensibles
  • Mettre à jour une vue existante sans casser les permissions déjà accordées

Dans quel contexte ?

Une équipe data doit fournir, chaque semaine, le même rapport combinant clients, commandes et trois conditions de filtrage à cinq personnes différentes. Copier-coller cette requête à chaque fois finit toujours par introduire une variante ou une erreur. En l'enregistrant sous forme de vue stats_clients, tout le monde interroge la même définition centralisée, ce que cette leçon détaille.

D'abord, un problème très concret d'équipe

Imagine une requête de rapport avec trois jointures, un GROUP BY et plusieurs conditions, que cinq personnes doivent réutiliser chaque semaine. Copier-coller ce pavé de SQL partout serait une source d'erreurs : une variante oubliée, une faute de frappe.

La solution : donner un nom à la requête

Une vue résout ce problème : elle enregistre la requête sous un nom, comme un raccourci. On peut ensuite l'interroger aussi simplement qu'une vraie table, avec un simple SELECT * FROM ma_vue.

Un point essentiel à bien comprendre ensuite

Une vue classique ne contient AUCUNE donnée propre. À chaque appel, la base réexécute la requête sous-jacente et recalcule le résultat à la volée. C'est pratique — toujours à jour — mais ça ne fait pas gagner de temps de calcul.

Une variante pour les cas où la vitesse compte plus

Une vue matérialisée stocke physiquement le résultat sur disque : plus rapide à lire, mais figée jusqu'au prochain rafraîchissement manuel via REFRESH.

TypeStockage des donnéesFraîcheurCas d'usage
Vue classiqueAucun, recalcul à chaque appelToujours à jourSimplifier une requête réutilisée
Vue matérialiséeSur disque, physiqueFigée jusqu'au REFRESHRapport lourd interrogé souvent

Prérequis

Les vues s'appuient directement sur les jointures et le GROUP BY déjà vus (leçons 4 et 5) : elles ne font qu'enregistrer une requête déjà maîtrisée sous un nom.

Un usage souvent négligé : la sécurité par abstraction

Une vue peut aussi volontairement exclure certaines colonnes sensibles (mot de passe, email) et ne montrer qu'un sous-ensemble sûr d'une table. On peut alors donner accès à cette vue sans jamais donner accès à la table complète.

Bonne pratique

Pour exposer des données à un rôle applicatif à privilèges restreints, crée une vue qui ne contient que les colonnes autorisées (CREATE VIEW utilisateurs_publics AS SELECT id, nom, avatar_url FROM utilisateurs) puis accorde GRANT SELECT uniquement sur cette vue, jamais sur la table complète.

Et la suite

Cette leçon fait le lien entre l'écriture de requêtes complexes — jointures, sous-requêtes, CTE — et leur mise à disposition simple et réutilisable pour toute une équipe.

Commandes & code

Vues (VIEW)

sql
-- Une vue est une requête nommée, exécutée à chaque appel (pas de stockage des données)
CREATE VIEW commandes_recentes AS
SELECT co.id, c.nom AS client, co.montant, co.cree_le
FROM commandes co
JOIN clients c ON c.id = co.client_id
WHERE co.cree_le > CURRENT_DATE - INTERVAL '30 days';

-- Utilisation comme une table normale
SELECT * FROM commandes_recentes WHERE montant > 200;

-- Vue pour simplifier un rapport complexe et le réutiliser partout
CREATE VIEW stats_clients AS
SELECT
    c.id,
    c.nom,
    COUNT(co.id) AS nb_commandes,
    COALESCE(SUM(co.montant), 0) AS total_depense,
    MAX(co.cree_le) AS derniere_commande
FROM clients c
LEFT JOIN commandes co ON co.client_id = c.id
GROUP BY c.id, c.nom;

SELECT * FROM stats_clients WHERE total_depense > 1000 ORDER BY total_depense DESC;

-- Vue pour restreindre l'accès à certaines colonnes (sécurité par abstraction)
CREATE VIEW utilisateurs_publics AS
SELECT id, nom, avatar_url  -- volontairement sans email ni mot_de_passe_hash
FROM utilisateurs;

GRANT SELECT ON utilisateurs_publics TO role_lecture_publique;

-- Modifier / supprimer une vue
CREATE OR REPLACE VIEW commandes_recentes AS
SELECT co.id, c.nom AS client, co.montant, co.cree_le
FROM commandes co
JOIN clients c ON c.id = co.client_id
WHERE co.cree_le > CURRENT_DATE - INTERVAL '7 days';  -- fenêtre réduite à 7 jours

DROP VIEW IF EXISTS commandes_recentes;

-- Vue matérialisée : stocke physiquement le résultat, à rafraîchir manuellement
CREATE MATERIALIZED VIEW rapport_ventes_mensuel AS
SELECT
    DATE_TRUNC('month', cree_le) AS mois,
    SUM(montant) AS total,
    COUNT(*) AS nb_commandes
FROM commandes
GROUP BY DATE_TRUNC('month', cree_le);

-- Rafraîchissement (nécessaire pour voir les nouvelles données)
REFRESH MATERIALIZED VIEW rapport_ventes_mensuel;

-- Rafraîchissement sans bloquer les lecteurs (nécessite un index unique)
CREATE UNIQUE INDEX ON rapport_ventes_mensuel (mois);
REFRESH MATERIALIZED VIEW CONCURRENTLY rapport_ventes_mensuel;

Résumé

  • Une vue classique n'a pas de stockage propre : elle réexécute sa requête à chaque appel.
  • Une vue matérialisée stocke physiquement le résultat, plus rapide à lire mais nécessite un REFRESH.
  • Les vues servent à simplifier des requêtes complexes, factoriser la logique et restreindre l'accès aux colonnes sensibles.
  • CREATE OR REPLACE VIEW évite de devoir DROP puis recréer les permissions.

Exercices pratiques

1 disponible
1

Mission : centraliser le rapport hebdomadaire et sécuriser l'accès aux utilisateurs

Objectif : Créer une vue pour factoriser un rapport, une vue matérialisée pour un rapport lourd, et une vue de restriction de colonnes.

Contexte

Cinq personnes de l'équipe data copient-collent chaque semaine la même requête à trois jointures pour obtenir les statistiques par client, avec des variantes qui commencent à diverger. Par ailleurs, l'équipe support demande un accès en lecture à la table utilisateurs, mais celle-ci contient une colonne mot_de_passe_hash qu'elle ne doit jamais voir.

Résoudre l’exercice →