|
A PostgreSQL database cluster (installation) contains one
or more named databases. Users and groups of users are shared across the entire cluster, but
no other data is shared across databases. Any given client connection to the server can access
only the data in a single database, the one specified in the connection request.
Note: Users of a cluster do not necessarily have the privilege to access every
database in the cluster. Sharing of user names means that there cannot be different users
named, say, joe in two databases in the same cluster; but the
system can be configured to allow joe access to only some of the
databases.
A database contains one or more named schemas, which in turn
contain tables. Schemas also contain other kinds of named objects, including data types,
functions, and operators. The same object name can be used in different schemas without
conflict; for example, both schema1 and myschema
may contain tables named mytable. Unlike databases, schemas are not
rigidly separated: a user may access objects in any of the schemas in the database he is
connected to, if he has privileges to do so.
There are several reasons why one might want to use schemas:
-
To allow many users to use one database without interfering with each other.
-
To organize database objects into logical groups to make them more manageable.
-
Third-party applications can be put into separate schemas so they cannot collide with
the names of other objects.
Schemas are analogous to directories at the operating system level, except that schemas
cannot be nested.
To create a separate schema, use the command CREATE SCHEMA. Give
the schema a name of your choice. For example:
CREATE SCHEMA myschema;
To create or access objects in a schema, write a qualified name
consisting of the schema name and table name separated by a dot:
schema.table
Actually, the even more general syntax
database.schema.table
can be used too, but at present this is just for pro-forma compliance with the SQL
standard; if you write a database name it must be the same as the database you are connected
to.
So to create a table in the new schema, use
CREATE TABLE myschema.mytable (
...
);
This works anywhere a table name is expected, including the table modification commands
and the data access commands discussed in the following chapters.
To drop a schema if it's empty (all objects in it have been dropped), use
DROP SCHEMA myschema;
To drop a schema including all contained objects, use
DROP SCHEMA myschema CASCADE;
See Section 2.10
for a description of the general mechanism behind this.
Often you will want to create a schema owned by someone else (since this is one of the
ways to restrict the activities of your users to well-defined namespaces). The syntax for
that is:
CREATE SCHEMA schemaname AUTHORIZATION username;
You can even omit the schema name, in which case the schema name will be the same as the
user name. See Section
2.8.6 for how this can be useful.
Schema names beginning with pg_ are reserved for system purposes
and may not be created by users.
In the previous sections we created tables without specifying any schema names. By
default, such tables (and other objects) are automatically put into a schema named "public". Every new database contains such a schema. Thus,
the following are equivalent:
CREATE TABLE products ( ... );
and
CREATE TABLE public.products ( ... );
Qualified names are tedious to write, and it's often best not to wire a particular schema
name into applications anyway. Therefore tables are often referred to by unqualified names, which consist of just the table name. The system
determines which table is meant by following a search path, which
is a list of schemas to look in. The first matching table in the search path is taken to be
the one wanted. If there is no match in the search path, an error is reported, even if
matching table names exist in other schemas in the database.
The first schema named in the search path is called the current schema. Aside from being
the first schema searched, it is also the schema in which new tables will be created if the CREATE TABLE command does not specify a schema name.
To show the current search path, use the following command:
SHOW search_path;
In the default setup this returns:
search_path
--------------
$user,public
The first element specifies that a schema with the same name as the current user is to be
searched. Since no such schema exists yet, this entry is ignored. The second element refers
to the public schema that we have seen already.
The first schema in the search path that exists is the default location for creating new
objects. That is the reason that by default objects are created in the public schema. When
objects are referenced in any other context without schema qualification (table
modification, data modification, or query commands) the search path is traversed until a
matching object is found. Therefore, in the default configuration, any unqualified access
again can only refer to the public schema.
To put our new schema in the path, we use
SET search_path TO myschema,public;
(We omit the $user here because we have no immediate need for
it.) And then we can access the table without schema qualification:
DROP TABLE mytable;
Also, since myschema is the first element in the path, new
objects would by default be created in it.
We could also have written
SET search_path TO myschema;
Then we no longer have access to the public schema without explicit qualification. There
is nothing special about the public schema except that it exists by default. It can be
dropped, too.
See also Section
6.13 for other ways to access the schema search path.
The search path works in the same way for data type names, function names, and operator
names as it does for table names. Data type and function names can be qualified in exactly
the same way as table names. If you need to write a qualified operator name in an
expression, there is a special provision: you must write
OPERATOR(schema.operator)
This is needed to avoid syntactic ambiguity. An example is
SELECT 3 OPERATOR(pg_catalog.+) 4;
In practice one usually relies on the search path for operators, so as not to have to
write anything so ugly as that.
By default, users cannot see the objects in schemas they do not own. To allow that, the
owner of the schema needs to grant the USAGE privilege on the
schema. To allow users to make use of the objects in the schema, additional privileges may
need to be granted, as appropriate for the object.
A user can also be allowed to create objects in someone else's schema. To allow that, the
CREATE privilege on the schema needs to be granted. Note that by
default, everyone has the CREATE privilege on the schema public. This allows all users that manage to connect to a given
database to create objects there. If you do not want to allow that, you can revoke that
privilege:
REVOKE CREATE ON public FROM PUBLIC;
(The first "public" is the schema, the second "public" means "every user".
In the first sense it is an identifier, in the second sense it is a reserved word, hence the
different capitalization; recall the guidelines from Section
1.1.1.)
In addition to public and user-created schemas, each database
contains a pg_catalog schema, which contains the system tables and
all the built-in data types, functions, and operators. pg_catalog
is always effectively part of the search path. If it is not named explicitly in the path
then it is implicitly searched before
searching the path's schemas. This ensures that built-in names will always be findable.
However, you may explicitly place pg_catalog at the end of your
search path if you prefer to have user-defined names override built-in names.
In PostgreSQL versions before 7.3, table names beginning
with pg_ were reserved. This is no longer true: you may create such
a table name if you wish, in any non-system schema. However, it's best to continue to avoid
such names, to ensure that you won't suffer a conflict if some future version defines a
system catalog named the same as your table. (With the default search path, an unqualified
reference to your table name would be resolved as the system catalog instead.) System
catalogs will continue to follow the convention of having names beginning with pg_, so that they will not conflict with unqualified user-table names
so long as users avoid the pg_ prefix.
Schemas can be used to organize your data in many ways. There are a few usage patterns
that are recommended and are easily supported by the default configuration:
-
If you do not create any schemas then all users access the public schema implicitly.
This simulates the situation where schemas are not available at all. This setup is
mainly recommended when there is only a single user or a few cooperating users in a
database. This setup also allows smooth transition from the non-schema-aware world.
-
You can create a schema for each user with the same name as that user. Recall that
the default search path starts with $user, which resolves to
the user name. Therefore, if each user has a separate schema, they access their own
schemas by default.
If you use this setup then you might also want to revoke access to the public schema
(or drop it altogether), so users are truly constrained to their own schemas.
-
To install shared applications (tables to be used by everyone, additional functions
provided by third parties, etc.), put them into separate schemas. Remember to grant
appropriate privileges to allow the other users to access them. Users can then refer to
these additional objects by qualifying the names with a schema name, or they can put the
additional schemas into their path, as they choose.
In the SQL standard, the notion of objects in the same schema being owned by different
users does not exist. Moreover, some implementations don't allow you to create schemas that
have a different name than their owner. In fact, the concepts of schema and user are nearly
equivalent in a database system that implements only the basic schema support specified in
the standard. Therefore, many users consider qualified names to really consist of username.tablename.
This is how PostgreSQL will effectively behave if you create a per-user schema for every
user.
Also, there is no concept of a public schema in the SQL
standard. For maximum conformance to the standard, you should not use (perhaps even remove)
the public schema.
Of course, some SQL database systems might not implement schemas at all, or provide
namespace support by allowing (possibly limited) cross-database access. If you need to work
with those systems, then maximum portability would be achieved by not using schemas at all.
|