5.8. Schémas

Un cluster de bases de données PostgreSQL contient une ou plusieurs bases nommées. Les utilisateurs et groupes d'utilisateurs sont partagés sur le cluster tout entier mais aucune autres données n'est partagées parmi les bases. Une connexion cliente donnée sur le serveur peut accéder aux données d'une seule base, celle spécifiée dans la connexion de requête.

Note : Les utilisateurs d'un cluster n'ont pas forcément le privilège d'accéder toutes les bases du cluster. Le partage des noms d'utilisateur veut dire 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 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, y compris des types de données, fonctions et opérateurs. Seul le nom d'objet peut être utilisé sans conflit; par exemple, schema1 et mon_schema peuvent tout les deux contenir des tables nommées mytable. Contrairement aux 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 lequel des schémas de la base de données auxquels il se connecte s'il a les privilèges pour le faire.

Il y a plusieurs raisons pour lesquelles quelqu'un voudrait utiliser les schémas:

Les schémas sont comparables aux répertoires au niveau du système d'exploitation. sauf que les schémas ne peuvent pas être imbriqués.

5.8.1. Créer un Schéma

Pour créer un schéma séparé, utilisez la commande CREATE SCHEMA. Donnez au schéma un nom de votre choix. Par exemple:

CREATE SCHEMA mon_schema;

Pour créer ou accéder aux objets dans un schéma, écrivez un nom qualifié qui consiste en le nom du schéma et le nom de la table séparés par un point:

schema.table

En fait, la syntaxe encore plus générale

database.schema.table

peut être utilisé aussi mais, pour le moment, ceci n'existe que pour être conforme au standard SQL; si vous écrivez un nom de base de données, il devrait être celui de la base auquel vous êtes connecté.

Donc, pour créer une table dans le nouveau schéma, utilisez

CREATE TABLE mon_schema.mytable (
 ...
);

Ceci marche partout ou un nom de table est attendue, y compris les commandes de modification de tables et les commandes d'accès aux données discutés dans les chapitres suivants.

Pour effacer un schéma vide (tout les objets a l'intérieur ont été effacés), utilisez

DROP SCHEMA mon_schema;

Pour effacer un schéma, y compris les objets qu'il contient, utilisez

DROP SCHEMA mon_schema CASCADE;

Lisez Section 5.10 pour une description du mécanisme général derrière tout ceci.

Cependant, vous voudriez modifier le schéma utilisé par quelqu'un d'autre (puisque c'est l'une des méthodes par lesquelles on peut restreindre l'activité de vos utilisateurs à des espaces de nom définis). La syntaxe pour ceci est:

CREATE SCHEMA schemaname AUTHORIZATION username;

Vous pouvez même omettre le nom du schéma auquel cas, le nom du schéma sera le même que le nom d'utilisateur. Voir Section 5.8.6 pour voir comment cela peut être utile.

Les noms de schéma commençant par pg_ sont réservés pour les besoins du système et ne peuvent pas être crées par les utilisateurs.

5.8.2. Le Schéma Public

Dans les sections précédentes, on créait des tables sans spécifier un nom de schéma. Par défaut, ces tables (et autres objets) sont automatiquement mis dans un schéma nommé << public >>. Toute nouvelle base de données contient un tel schéma. Donc, ces instructions sont équivalents:

CREATE TABLE produits ( ... );

and

CREATE TABLE public.produits ( ... );

5.8.3. Le Chemin de Recherche de Schéma

Les noms qualifiés sont pénibles à écrire et il est, de toutes façons, préférable de ne pas coder un nom de schéma dans une application. Donc, les tables sont souvent appelées par des noms non qualifiés qui s'apparente souvent au nom de la table lui même. Le système détermine quel table est appelée en suivant un chemin de recherche qui est une liste de schémas a regarder. La première table correspondante est considérée comme la table voulue. S'il n'y a pas de correspondance, une erreur est soulevée, même si des noms de table correspondants existent dans d'autres schémas dans la base.

Le premier schéma dans le chemin de recherche est appelé le schéma courant. En plus d'être le premier schéma parcouru, il est aussi le schéma dans lequel de nouvelles tables seront créées si la commande CREATE TABLE ne précise pas de nom de schéma.

Pour voir le chemin de recherche courant, utilisez la commande suivante:

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 avec le même nom que l'utilisateur en cours doit être parcouru. Le deuxième élément renvoie au schéma public que nous avons déjà vu.

Le premier schéma existant dans le chemin de recherche est l'endroit par défaut pour la création de nouveaux objets. Ceci est la raison pour laquelle les objets sont créés dans le schéma public. Quand les objets sont liés dans tout autre contexte sans une qualification de schéma (modification de table, modification de données ou requête de commande), le chemin de recherche est traversé jusqu'à ce qu'un objet correspondant soit trouvé. Donc, dans la configuration par défaut, tout accès non qualifié ne peut que se référer au schéma public.

Pour mettre notre nouveau schéma dans le chemin, nous utilisons

SET search_path TO mon_schema,public;

(Nous ne mettons pas le $user ici car nous n'en avons pas besoin pour l'instant.) Et nous pouvons pas accéder à la table sans qualification de schéma:

DROP TABLE mytable;

Aussi, puisque mon_schema est le premier élément dans le chemin, les nouveaux objets seront crées à l'intérieur.

On pourrait aussi écrire

SET search_path TO mon_schema;

Alors nous n'avons pas accès au schéma public sans qualification explicite. Il n'y a rien de spécial à propos du schéma public hormis le fait qu'il existe par défaut. Il peut aussi être effacé.

Voir aussi Section 9.13 qui detaille les autres façons d'accéder au chemin de recherche de schéma.

Le chemin de recherche fonctionne de la même façon pour les noms de type de données, noms de fonction, et noms d'opérateur que pour le noms de tables. Les types de données et de fonction peuvent être qualifiés de la même façon que les noms de table. Si vous avez besoin d'écrire un nom d'opérateur qualifié dans une expression, il y'a une condition spéciale: vous devez écrire

OPERATOR(schéma.opérateur)

Ceci est nécessaire afin d'éviter une ambiguïté syntaxique. Un exemple est

SELECT 3 OPERATOR(pg_catalog.+) 4;

En pratique, on dépend souvent du chemin de recherche pour les opérateurs, afin de ne pas avoir à écrire quelque chose d'aussi peu présentable.

5.8.4. Schémas et Privilèges

Par défaut, les utilisateurs ne peuvent pas accéder aux objets dans les schémas qui ne leurs appartiennent pas. Pour autoriser cela, le propriétaire du schéma doit donner le privilège USAGE sur le schéma. Pour autoriser les utilisateurs à manipuler les objets d'un schéma, des privilèges supplémentaires devront peut-être être accordés, suivant l'objet.

Un utilisateur peut aussi être autorisé à créer des objets dans le schéma de quelqu'un d'autre. Pour permettre ceci, le privilège CREATE doit être accordé. Notez que, par défaut, tout le monde à les privilèges CREATE et USAGE sur le schéma public. Ceci permet à tout les utilisateurs qui sont capables de se connecter à une base de données de créer des objets dans son schéma public. Si vous ne souhaitez pas ce comportement, vous pouvez révoquer ce privilège:

REVOKE CREATE ON SCHEMA public FROM PUBLIC;

(Le premier << public >> est le schéma, le second << public >> veut dire << chaque utilisateur >>. Dans le premier cas, c'est un identifiant. Dans le second, c'est un mot réservé, d'où la casse différente. Souvenez vous des règles de Section 4.1.1.)

5.8.5. Le Catalogue de Système de Schéma

En plus des schémas publics crées par les utilisateurs, chaque base de données contient un schéma pg_catalog, qui contient les tables systèmes et tous les types de données, fonctions et opérateurs intégrés. pg_catalog fait toujours, de fait, partie du chemin de recherche. S'il n'est pas nommé explicitement dans le chemin, il est parcouru implicitement avant la recherche dans les schémas du chemin. Ceci garantit qui les noms internes seront toujours trouvables . Par contre, vous pouvez explicitement placer pg_catalog à la fin si vous préférez que les noms définis par les utilisateurs surchargent 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. Ceci n'est plus vrai: vous pouvez créer une telle table si vous le voulez dans n'importe quel schéma non système. Par contre, il vaut mieux continuer d'éviter de tels noms pour garantir que vous n'aurez pas de conflit si une prochaine version définit une table système qui porte le même nom que votre table. (Avec le chemin de recherche par défaut, une référence non qualifiée à votre table pointera au lieu vers la table système.) Les tables systèmes continueront de suivre la convention de porter des noms commençant par pg_ pour qu'ils n'aient pas de conflit avec des noms de table non qualifiés tant que les utilisateurs éviteront le préfixe pg_.

5.8.6. Méthodes d'Utilisation

Les schémas peuvent être utilisés pour organiser vos données de plusieurs manières. Il y en a plusieurs qui sont recommandés et sont facilement supportés par la configuration par défaut:

5.8.7. Portabilité

Dans le standard SQL, la notion d'objets dans le même schéma appartenant à des utilisateurs différents n'existe pas. De plus, certaines implémentations ne vous 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'implémente que le support basique des schémas spécifiés dans le standard. A partir de ce constat, beaucoup d'utilisateurs considèrent les noms qualifiés qui correspondre réellement à utilisateur.table. C'est comme cela que PostgreSQL se comporte si vous créez un schéma par utilisateur pour chaque utilisateur.

De plus, il n'y a aucun concept d'un schéma public dans le standard SQL. Pour plus de conformité au standard, vous ne devriez pas utilisez (et sans doute effacer) le schéma public.

Bien sur, certains systèmes de bases de données n'implémentent pas du tout les schémas. ou donnent le support d'espace de nommage en autorisant (peut-être de façon limité) des accès sur plusieurs bases de données alors la portabilité maximale sera obtenue en n'utilisant pas du tout les schémas.