5.7. Schémas
Un cluster de bases de données PostgreSQL™ contient une ou plusieurs
bases nommées. Si les utilisateurs et groupes d'utilisateurs sont
partagés sur l'ensemble du cluster, aucune autre donnée n'est
partagée. Une connexion cliente donnée sur le serveur ne peut accéder
qu'aux données d'une seule base, celle indiquée dans la requête de
connexion.
Note
Les utilisateurs d'un cluster n'ont pas obligatoirement le droit
d'accéder à toutes les bases du cluster. Le partage des noms
d'utilisateur signifie qu'il ne peut pas y avoir plusieurs
utilisateurs nommés joe, par exemple,
dans deux bases du même cluster ; mais le système peut être
configuré pour n'autoriser joe à accéder
qu'à certaines bases.
Une base de données contient un ou plusieurs schémas nommés qui, eux, contiennent des tables. Les
schémas contiennent aussi d'autres types d'objets nommés (types de
données, fonctions et opérateurs, par exemple). Le même nom d'objet
peut être utilisé dans différents schémas sans conflit ; par exemple,
schema1 et mon_schema peuvent tous les deux contenir une table
nommée ma_table. À la différence des bases
de données, les schémas ne sont pas séparés de manière rigide : un
utilisateur peut accéder aux objets de n'importe quel schéma de la
base de données à laquelle il est connecté, sous réserve qu'il en ait
le droit.
Il existe plusieurs raisons d'utiliser les schémas :
-
pour autoriser de nombreux utilisateurs à utiliser une base de
données sans interférences entre eux ;
-
pour organiser les objets de la base de données en groupes
logiques afin de faciliter leur gestion ;
-
les applications tiers peuvent être placées dans des schémas
séparés pour éviter les collisions avec les noms d'autres
objets.
Les schémas sont comparables aux répertoires du système
d'exploitation, à ceci près qu'ils ne peuvent pas être imbriqués.
Pour créer un schéma, on utilise la commande CREATE SCHEMA. Le
nom du schéma est libre. Par exemple :
CREATE SCHEMA mon_schema;
Pour créer ou accéder aux objets d'un schéma, on écrit un
nom qualifié constitué du nom du schéma
et du nom de la table séparés par un point :
schema.table
Cela fonctionne partout où un nom de table est attendu, ce qui
inclue les commandes de modification de la table et les commandes
d'accès aux données discutées dans les chapitres suivants. (Pour
des raisons de simplification, il n'est question que de tables,
mais les mêmes principes s'appliquent à d'autres types d'objets
nommés, comme les types et les fonctions.)
En fait, la syntaxe encore plus générale
base.schema.table
peut aussi être utilisée, mais à l'heure actuelle, cette syntaxe
n'existe que pour des raisons de conformité avec le standard SQL.
Si un nom de base de données est précisé, ce doit être celui de la
base à laquelle l'utilisateur est connecté.
Pour créer une table dans le nouveau schéma, on utilise
CREATE TABLE mon_schema.ma_table (
...
);
Pour effacer un schéma vide (tous les objets qu'il contient ont été
supprimés), on utilise
DROP SCHEMA mon_schema;
Pour effacer un schéma et les objets qu'il contient, on utilise
DROP SCHEMA mon_schema CASCADE;
La Section 5.11,
« Gestion des dépendances » décrit le mécanisme
général sous-jacent.
Il n'est pas rare de vouloir créer un schéma dont un autre
utilisateur est propriétaire (puisque c'est l'une des méthodes de
restriction de l'activité des utilisateurs à des
namespaces
pré-définis). La syntaxe en est :
CREATE SCHEMA nom_schema AUTHORIZATION nom_utilisateur;
Le nom du schéma peut être omis, auquel cas le nom de l'utilisateur
est utilisé. Voir la Section 5.7.6,
« Utilisation » pour en connaître l'utilité.
Les noms de schéma commençant par pg_ sont
réservés pour les besoins du système et ne peuvent être créés par
les utilisateurs.
Dans les sections précédentes, les tables sont créées sans qu'un
nom de schéma soit indiqué. Par défaut, ces tables (et les autres
objets) sont automatiquement placées dans un schéma nommé
« public ». Toute nouvelle
base de données contient un tel schéma. Les instructions suivantes
sont donc équivalentes :
CREATE TABLE produits ( ... );
et
CREATE TABLE public.produits ( ... );
5.7.3. Chemin de parcours des schémas
Non seulement l'écriture de noms qualifiés est contraignante, mais
il est, de toute façon, préférable de ne pas fixer un nom de schéma
dans les applications. De ce fait, les tables sont souvent appelées
par des noms non-qualifiés, soit le seul
nom de la table. Le système détermine la table appelée en suivant
un chemin de recherche, liste de schémas
dans lesquels chercher. La première table correspondante est
considérée comme la table voulue. S'il n'y a pas de correspondance,
une erreur est remontée, même si des noms de table correspondant
existent dans d'autres schémas de la base.
Le premier schéma du chemin de recherche est appelé schéma courant.
En plus d'être le premier schéma parcouru, il est aussi le schéma
dans lequel les nouvelles tables sont créées si la commande
CREATE TABLE
ne
précise pas de nom de schéma.
Le chemin de recherche courant est affiché à l'aide de la commande
:
SHOW search_path;
Dans la configuration par défaut, ceci renvoie :
search_path
--------------
"$user",public
Le premier élément précise qu'un schéma de même nom que
l'utilisateur courant est recherché. En l'absence d'un tel schéma,
l'entrée est ignorée. Le deuxième élément renvoie au schéma public
précédemment évoqué.
C'est, par défaut, dans le premier schéma du chemin de recherche
qui existe que sont créés les nouveaux objets. C'est la raison pour
laquelle les objets sont créés, par défaut, dans le schéma public.
Lorsqu'il est fait référence à un objet, dans tout autre contexte,
sans qualification par un schéma (modification de table,
modification de données ou requêtes), le chemin de recherche est
traversé jusqu'à ce qu'un objet correspondant soit trouvé. C'est
pourquoi, dans la configuration par défaut, tout accès non qualifié
ne peut que se référer au schéma public.
Pour ajouter un schéma au chemin, on écrit :
SET search_path TO mon_schema,public;
($user est omis à ce niveau car il n'est
pas immédiatement nécessaire.) Il est alors possible d'à la table
sans qualification par un schéma :
DROP TABLE ma_table;
Puisque mon_schema est le premier élément
du chemin, les nouveaux objets sont, par défaut, créés dans ce
schéma.
On peut aussi écrire
SET search_path TO mon_schema;
Dans ce cas, le schéma public n'est plus accessible sans
qualification explicite. Hormis le fait qu'il existe par défaut, le
schéma public n'a rien de spécial. Il peut même être effacé.
On peut également se référer à la Section 9.19,
« Fonctions d'informations système » qui détaille les
autres façons de manipuler le chemin de recherche des schémas.
Le chemin de recherche fonctionne de la même façon pour les noms de
type de données, les noms de fonction et les noms d'opérateur que
pour les noms de tables. Les noms des types de données et des
fonctions peuvent être qualifiés de la même façon que les noms de
table. S'il est nécessaire d'écrire un nom d'opérateur qualifié
dans une expression, il y a une condition spéciale : il faut écrire
OPERATOR(schéma.opérateur)
Cela afin d'éviter toute ambiguïté syntaxique. En voici un exemple
SELECT 3 OPERATOR(pg_catalog.+) 4;
En pratique, il est préférable de s'en remettre au chemin de
recherche pour les opérateurs, afin de ne pas avoir à écrire
quelque chose d'aussi étrange.
5.7.4. Schémas et privilèges
Par défaut, les utilisateurs ne peuvent pas accéder aux objets
présents dans les schémas qui ne leur appartiennent pas. Pour le
permettre, le propriétaire du schéma doit granter le droit
USAGE sur le schéma. Pour autoriser les
utilisateurs à manipuler les objets d'un schéma, des privilèges
supplémentaires doivent peut-être être accordés, en fonction de
l'objet.
Un utilisateur peut aussi être autorisé à créer des objets dans
schéma de quelqu'un d'autre. Pour cela, le privilège CREATE sur le schéma doit être accordé. Par défaut,
tout le monde bénéficie des droits CREATE
et USAGE sur le schéma public. Cela permet à tous les utilisateurs qui
peuvent se connecter à une base de données de créer des objets dans
son schéma public. Si cela ne doit pas
être le cas, ce privilège peut être révoqué :
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
Le premier « public » est le
schéma, le second « public »
signifie « tout utilisateur ».
Dans le premier cas, c'est un identifiant, dans le second, un mot
clé, d'où la casse différente. (Se reporter aux règles de la
Section 4.1.1,
« Identifieurs et mots clés ».)
5.7.5. Le schéma du catalogue système
En plus du schéma public et de ceux créés
par les utilisateurs, chaque base de données contient un schéma
pg_catalog. Celui-ci contient les tables
systèmes et tous les types de données, fonctions et opérateurs
intégrés. pg_catalog est toujours dans le
chemin de recherche. S'il n'est pas nommé explicitement dans le
chemin, il est parcouru implicitement
avant
le parcours des schémas du chemin.
Cela garantit que les noms internes sont toujours accessibles. En
revanche, pg_catalog peut être
explicitement placé à la fin si les noms utilisateur doivent
surcharger les noms internes.
Dans les versions de PostgreSQL™ antérieures à la 7.3, les
noms de table commençant par pg_ étaient
réservés. Cela n'est plus vrai : une telle table peut être créée
dans n'importe quel schéma qui n'est pas un schéma système. En
revanche, il est préférable de continuer à éviter d'utiliser de
tels noms pour se prémunir d'éventuels conflits si une version
ultérieure devait définir une table système qui porte le même nom
que la table créée. (Le chemin de recherche par défaut implique
qu'une référence non qualifiée à cette table pointe sur la table
système). Les tables systèmes continueront de suivre la convention
qui leur impose des noms préfixés par pg_.
Il n'y a donc pas de conflit possible avec des noms de table
utilisateur non qualifiés, sous réserve que les utilisateurs
évitent le préfixe pg_.
Les schémas peuvent être utilisés de différentes façons pour
organiser les données. Certaines d'entre elles, recommandées, sont
facilement supportés par la configuration par défaut :
-
si aucun schéma n'est créé, alors tous les utilisateurs ont
implicitement accès au schéma public. Cela permet de simuler
une situation dans laquelle les schémas ne sont pas
disponibles. Cette situation est essentiellement recommandée
pour les utilisateurs seuls ou quelques d'utilisateurs
concurents au sein d'une base de données. Cette configuration
permet aussi une transition en douceur depuis un monde où les
schémas sont inconnus ;
-
un schéma peut être créé pour chaque utilisateur, avec un nom
identique à celui de l'utilisateur. Le chemin de recherche
par défaut commence par $user, ce
qui correspond au nom de l'utilisateur. Si chaque utilisateur
dispose d'un schéma distinct, tout utilisateur accède, par
défaut, à son propre schéma. Dans cette configuration, il est
possible de révoquer l'accès au schéma public (voire de
supprimer ce schéma) pour contraindre les utilisateurs à leur
propre schéma ;
-
l'installation d'applications partagées (tables utilisables
par tout le monde, fonctionnalités supplémentaires fournies
par des applications tiers, etc) peut se faire dans des
schémas distincts. Il faut alors accorder des privilèges
appropriés pour permettre aux autres utilisateurs d'y
accéder. Les utilisateurs peuvent alors se référer à ces
objets additionnels en qualifiant leurs noms du nom de schéma
ou ajouter les schémas supplémentaires dans leur chemin de
recherche, au choix.
Dans le standard SQL, la notion d'objets du même schéma appartenant
à des utilisateurs différents n'existe pas. De plus, certaines
implantations ne permettent pas de créer des schémas qui ont un nom
différent de celui de leur propriétaire. En fait, les concepts de
schéma et d'utilisateur sont presque équivalents dans un système de
base de données qui n'implante que le support basique des schémas
tel que spécifié dans le standard. De ce fait, beaucoup
d'utilisateurs considèrent les noms qualifiés comme correspondant
en réalité à
utilisateur
.
table
. C'est comme cela que
PostgreSQL™ se comporte si
un schéma utilisateur est créé pour chaque utilisateur.
Le concept de schéma public n'existe pas
non plus dans le standard SQL. Pour plus de conformité au standard,
le schéma public ne devrait pas être
utilisé (voire être supprimé).
Certains systèmes de bases de données n'implantent pas du tout les
schémas, ou fournissent le support de
namespace
en
autorisant (peut-être de façon limitée) l'accès inter-bases de
données. Dans ce cas, la portabilité maximale sera obtenue en
n'utilisant pas les schémas.