summaryrefslogtreecommitdiffstats
path: root/doc/src/sgml/html/ddl-schemas.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/html/ddl-schemas.html')
-rw-r--r--doc/src/sgml/html/ddl-schemas.html329
1 files changed, 329 insertions, 0 deletions
diff --git a/doc/src/sgml/html/ddl-schemas.html b/doc/src/sgml/html/ddl-schemas.html
new file mode 100644
index 0000000..8140b15
--- /dev/null
+++ b/doc/src/sgml/html/ddl-schemas.html
@@ -0,0 +1,329 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.9. Schemas</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-rowsecurity.html" title="5.8. Row Security Policies" /><link rel="next" href="ddl-inherit.html" title="5.10. Inheritance" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.9. Schemas</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 16.2 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-inherit.html" title="5.10. Inheritance">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-SCHEMAS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.9. Schemas <a href="#DDL-SCHEMAS" class="id_link">#</a></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-CREATE">5.9.1. Creating a Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PUBLIC">5.9.2. The Public Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PATH">5.9.3. The Schema Search Path</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PRIV">5.9.4. Schemas and Privileges</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-CATALOG">5.9.5. The System Catalog Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS">5.9.6. Usage Patterns</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PORTABILITY">5.9.7. Portability</a></span></dt></dl></div><a id="id-1.5.4.11.2" class="indexterm"></a><p>
+ A <span class="productname">PostgreSQL</span> database cluster contains
+ one or more named databases. Roles and a few other object types are
+ shared across the entire cluster. A client connection to the server
+ can only access data in a single database, the one specified in the
+ connection request.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Users of a cluster do not necessarily have the privilege to access every
+ database in the cluster. Sharing of role names means that there
+ cannot be different roles named, say, <code class="literal">joe</code> in two databases
+ in the same cluster; but the system can be configured to allow
+ <code class="literal">joe</code> access to only some of the databases.
+ </p></div><p>
+ A database contains one or more named <em class="firstterm">schemas</em>, 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 <code class="literal">schema1</code> and <code class="literal">myschema</code> can
+ contain tables named <code class="literal">mytable</code>. Unlike databases,
+ schemas are not rigidly separated: a user can access objects in any
+ of the schemas in the database they are connected to, if they have
+ privileges to do so.
+ </p><p>
+ There are several reasons why one might want to use schemas:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ To allow many users to use one database without interfering with
+ each other.
+ </p></li><li class="listitem"><p>
+ To organize database objects into logical groups to make them
+ more manageable.
+ </p></li><li class="listitem"><p>
+ Third-party applications can be put into separate schemas so
+ they do not collide with the names of other objects.
+ </p></li></ul></div><p>
+
+ Schemas are analogous to directories at the operating system level,
+ except that schemas cannot be nested.
+ </p><div class="sect2" id="DDL-SCHEMAS-CREATE"><div class="titlepage"><div><div><h3 class="title">5.9.1. Creating a Schema <a href="#DDL-SCHEMAS-CREATE" class="id_link">#</a></h3></div></div></div><a id="id-1.5.4.11.7.2" class="indexterm"></a><p>
+ To create a schema, use the <a class="xref" href="sql-createschema.html" title="CREATE SCHEMA"><span class="refentrytitle">CREATE SCHEMA</span></a>
+ command. Give the schema a name
+ of your choice. For example:
+</p><pre class="programlisting">
+CREATE SCHEMA myschema;
+</pre><p>
+ </p><a id="id-1.5.4.11.7.4" class="indexterm"></a><a id="id-1.5.4.11.7.5" class="indexterm"></a><p>
+ To create or access objects in a schema, write a
+ <em class="firstterm">qualified name</em> consisting of the schema name and
+ table name separated by a dot:
+</p><pre class="synopsis">
+<em class="replaceable"><code>schema</code></em><code class="literal">.</code><em class="replaceable"><code>table</code></em>
+</pre><p>
+ This works anywhere a table name is expected, including the table
+ modification commands and the data access commands discussed in
+ the following chapters.
+ (For brevity we will speak of tables only, but the same ideas apply
+ to other kinds of named objects, such as types and functions.)
+ </p><p>
+ Actually, the even more general syntax
+</p><pre class="synopsis">
+<em class="replaceable"><code>database</code></em><code class="literal">.</code><em class="replaceable"><code>schema</code></em><code class="literal">.</code><em class="replaceable"><code>table</code></em>
+</pre><p>
+ 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.
+ </p><p>
+ So to create a table in the new schema, use:
+</p><pre class="programlisting">
+CREATE TABLE myschema.mytable (
+ ...
+);
+</pre><p>
+ </p><a id="id-1.5.4.11.7.9" class="indexterm"></a><p>
+ To drop a schema if it's empty (all objects in it have been
+ dropped), use:
+</p><pre class="programlisting">
+DROP SCHEMA myschema;
+</pre><p>
+ To drop a schema including all contained objects, use:
+</p><pre class="programlisting">
+DROP SCHEMA myschema CASCADE;
+</pre><p>
+ See <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a> for a description of the general
+ mechanism behind this.
+ </p><p>
+ 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:
+</p><pre class="programlisting">
+CREATE SCHEMA <em class="replaceable"><code>schema_name</code></em> AUTHORIZATION <em class="replaceable"><code>user_name</code></em>;
+</pre><p>
+ You can even omit the schema name, in which case the schema name
+ will be the same as the user name. See <a class="xref" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">Section 5.9.6</a> for how this can be useful.
+ </p><p>
+ Schema names beginning with <code class="literal">pg_</code> are reserved for
+ system purposes and cannot be created by users.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PUBLIC"><div class="titlepage"><div><div><h3 class="title">5.9.2. The Public Schema <a href="#DDL-SCHEMAS-PUBLIC" class="id_link">#</a></h3></div></div></div><a id="id-1.5.4.11.8.2" class="indexterm"></a><p>
+ 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 <span class="quote">“<span class="quote">public</span>”</span>. Every new
+ database contains such a schema. Thus, the following are equivalent:
+</p><pre class="programlisting">
+CREATE TABLE products ( ... );
+</pre><p>
+ and:
+</p><pre class="programlisting">
+CREATE TABLE public.products ( ... );
+</pre><p>
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PATH"><div class="titlepage"><div><div><h3 class="title">5.9.3. The Schema Search Path <a href="#DDL-SCHEMAS-PATH" class="id_link">#</a></h3></div></div></div><a id="id-1.5.4.11.9.2" class="indexterm"></a><a id="id-1.5.4.11.9.3" class="indexterm"></a><a id="id-1.5.4.11.9.4" class="indexterm"></a><p>
+ 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 <em class="firstterm">unqualified names</em>,
+ which consist of just the table name. The system determines which table
+ is meant by following a <em class="firstterm">search path</em>, 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.
+ </p><p>
+ The ability to create like-named objects in different schemas complicates
+ writing a query that references precisely the same objects every time. It
+ also opens up the potential for users to change the behavior of other
+ users' queries, maliciously or accidentally. Due to the prevalence of
+ unqualified names in queries and their use
+ in <span class="productname">PostgreSQL</span> internals, adding a schema
+ to <code class="varname">search_path</code> effectively trusts all users having
+ <code class="literal">CREATE</code> privilege on that schema. When you run an
+ ordinary query, a malicious user able to create objects in a schema of
+ your search path can take control and execute arbitrary SQL functions as
+ though you executed them.
+ </p><a id="id-1.5.4.11.9.7" class="indexterm"></a><p>
+ 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 <code class="command">CREATE TABLE</code>
+ command does not specify a schema name.
+ </p><a id="id-1.5.4.11.9.9" class="indexterm"></a><p>
+ To show the current search path, use the following command:
+</p><pre class="programlisting">
+SHOW search_path;
+</pre><p>
+ In the default setup this returns:
+</p><pre class="screen">
+ search_path
+--------------
+ "$user", public
+</pre><p>
+ The first element specifies that a schema with the same name as
+ the current user is to be searched. If no such schema exists,
+ the entry is ignored. The second element refers to the
+ public schema that we have seen already.
+ </p><p>
+ 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.
+ </p><p>
+ To put our new schema in the path, we use:
+</p><pre class="programlisting">
+SET search_path TO myschema,public;
+</pre><p>
+ (We omit the <code class="literal">$user</code> here because we have no
+ immediate need for it.) And then we can access the table without
+ schema qualification:
+</p><pre class="programlisting">
+DROP TABLE mytable;
+</pre><p>
+ Also, since <code class="literal">myschema</code> is the first element in
+ the path, new objects would by default be created in it.
+ </p><p>
+ We could also have written:
+</p><pre class="programlisting">
+SET search_path TO myschema;
+</pre><p>
+ 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.
+ </p><p>
+ See also <a class="xref" href="functions-info.html" title="9.26. System Information Functions and Operators">Section 9.26</a> for other ways to manipulate
+ the schema search path.
+ </p><p>
+ 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
+</p><pre class="synopsis">
+<code class="literal">OPERATOR(</code><em class="replaceable"><code>schema</code></em><code class="literal">.</code><em class="replaceable"><code>operator</code></em><code class="literal">)</code>
+</pre><p>
+ This is needed to avoid syntactic ambiguity. An example is:
+</p><pre class="programlisting">
+SELECT 3 OPERATOR(pg_catalog.+) 4;
+</pre><p>
+ In practice one usually relies on the search path for operators,
+ so as not to have to write anything so ugly as that.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PRIV"><div class="titlepage"><div><div><h3 class="title">5.9.4. Schemas and Privileges <a href="#DDL-SCHEMAS-PRIV" class="id_link">#</a></h3></div></div></div><a id="id-1.5.4.11.10.2" class="indexterm"></a><p>
+ By default, users cannot access any objects in schemas they do not
+ own. To allow that, the owner of the schema must grant the
+ <code class="literal">USAGE</code> privilege on the schema. By default, everyone
+ has that privilege on the schema <code class="literal">public</code>. To allow
+ users to make use of the objects in a schema, additional privileges might
+ need to be granted, as appropriate for the object.
+ </p><p>
+ A user can also be allowed to create objects in someone else's schema. To
+ allow that, the <code class="literal">CREATE</code> privilege on the schema needs to
+ be granted. In databases upgraded from
+ <span class="productname">PostgreSQL</span> 14 or earlier, everyone has that
+ privilege on the schema <code class="literal">public</code>.
+ Some <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">usage patterns</a> call for
+ revoking that privilege:
+</p><pre class="programlisting">
+REVOKE CREATE ON SCHEMA public FROM PUBLIC;
+</pre><p>
+ (The first <span class="quote">“<span class="quote">public</span>”</span> is the schema, the second
+ <span class="quote">“<span class="quote">public</span>”</span> means <span class="quote">“<span class="quote">every user</span>”</span>. In the
+ first sense it is an identifier, in the second sense it is a
+ key word, hence the different capitalization; recall the
+ guidelines from <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS" title="4.1.1. Identifiers and Key Words">Section 4.1.1</a>.)
+ </p></div><div class="sect2" id="DDL-SCHEMAS-CATALOG"><div class="titlepage"><div><div><h3 class="title">5.9.5. The System Catalog Schema <a href="#DDL-SCHEMAS-CATALOG" class="id_link">#</a></h3></div></div></div><a id="id-1.5.4.11.11.2" class="indexterm"></a><p>
+ In addition to <code class="literal">public</code> and user-created schemas, each
+ database contains a <code class="literal">pg_catalog</code> schema, which contains
+ the system tables and all the built-in data types, functions, and
+ operators. <code class="literal">pg_catalog</code> is always effectively part of
+ the search path. If it is not named explicitly in the path then
+ it is implicitly searched <span class="emphasis"><em>before</em></span> searching the path's
+ schemas. This ensures that built-in names will always be
+ findable. However, you can explicitly place
+ <code class="literal">pg_catalog</code> at the end of your search path if you
+ prefer to have user-defined names override built-in names.
+ </p><p>
+ Since system table names begin with <code class="literal">pg_</code>, it is best to
+ avoid such names to ensure that you won't suffer a conflict if some
+ future version defines a system table named the same as your
+ table. (With the default search path, an unqualified reference to
+ your table name would then be resolved as the system table instead.)
+ System tables will continue to follow the convention of having
+ names beginning with <code class="literal">pg_</code>, so that they will not
+ conflict with unqualified user-table names so long as users avoid
+ the <code class="literal">pg_</code> prefix.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PATTERNS"><div class="titlepage"><div><div><h3 class="title">5.9.6. Usage Patterns <a href="#DDL-SCHEMAS-PATTERNS" class="id_link">#</a></h3></div></div></div><p>
+ Schemas can be used to organize your data in many ways.
+ A <em class="firstterm">secure schema usage pattern</em> prevents untrusted
+ users from changing the behavior of other users' queries. When a database
+ does not use a secure schema usage pattern, users wishing to securely
+ query that database would take protective action at the beginning of each
+ session. Specifically, they would begin each session by
+ setting <code class="varname">search_path</code> to the empty string or otherwise
+ removing schemas that are writable by non-superusers
+ from <code class="varname">search_path</code>. There are a few usage patterns
+ easily supported by the default configuration:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Constrain ordinary users to user-private schemas.
+ To implement this pattern, first ensure that no schemas have
+ public <code class="literal">CREATE</code> privileges. Then, for every user
+ needing to create non-temporary objects, create a schema with the
+ same name as that user, for example
+ <code class="literal">CREATE SCHEMA alice AUTHORIZATION alice</code>.
+ (Recall that the default search path starts
+ with <code class="literal">$user</code>, which resolves to the user
+ name. Therefore, if each user has a separate schema, they access
+ their own schemas by default.) This pattern is a secure schema
+ usage pattern unless an untrusted user is the database owner or
+ has been granted <code class="literal">ADMIN OPTION</code> on a relevant role,
+ in which case no secure schema usage pattern exists.
+ </p><p>
+ In <span class="productname">PostgreSQL</span> 15 and later, the default
+ configuration supports this usage pattern. In prior versions, or
+ when using a database that has been upgraded from a prior version,
+ you will need to remove the public <code class="literal">CREATE</code>
+ privilege from the <code class="literal">public</code> schema (issue
+ <code class="literal">REVOKE CREATE ON SCHEMA public FROM PUBLIC</code>).
+ Then consider auditing the <code class="literal">public</code> schema for
+ objects named like objects in schema <code class="literal">pg_catalog</code>.
+ </p></li><li class="listitem"><p>
+ Remove the public schema from the default search path, by modifying
+ <a class="link" href="config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE" title="20.1.2. Parameter Interaction via the Configuration File"><code class="filename">postgresql.conf</code></a>
+ or by issuing <code class="literal">ALTER ROLE ALL SET search_path =
+ "$user"</code>. Then, grant privileges to create in the public
+ schema. Only qualified names will choose public schema objects. While
+ qualified table references are fine, calls to functions in the public
+ schema <a class="link" href="typeconv-func.html" title="10.3. Functions">will be unsafe or
+ unreliable</a>. If you create functions or extensions in the public
+ schema, use the first pattern instead. Otherwise, like the first
+ pattern, this is secure unless an untrusted user is the database owner
+ or has been granted <code class="literal">ADMIN OPTION</code> on a relevant role.
+ </p></li><li class="listitem"><p>
+ Keep the default search path, and grant privileges to create in the
+ public schema. All users access the public schema implicitly. This
+ simulates the situation where schemas are not available at all, giving
+ a smooth transition from the non-schema-aware world. However, this is
+ never a secure pattern. It is acceptable only when the database has a
+ single user or a few mutually-trusting users. In databases upgraded
+ from <span class="productname">PostgreSQL</span> 14 or earlier, this is the
+ default.
+ </p></li></ul></div><p>
+ </p><p>
+ For any pattern, 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 search path, as they choose.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PORTABILITY"><div class="titlepage"><div><div><h3 class="title">5.9.7. Portability <a href="#DDL-SCHEMAS-PORTABILITY" class="id_link">#</a></h3></div></div></div><p>
+ In the SQL standard, the notion of objects in the same schema
+ being owned by different users does not exist. Moreover, some
+ implementations do not 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
+ <code class="literal"><em class="replaceable"><code>user_name</code></em>.<em class="replaceable"><code>table_name</code></em></code>.
+ This is how <span class="productname">PostgreSQL</span> will effectively
+ behave if you create a per-user schema for every user.
+ </p><p>
+ Also, there is no concept of a <code class="literal">public</code> schema in the
+ SQL standard. For maximum conformance to the standard, you should
+ not use the <code class="literal">public</code> schema.
+ </p><p>
+ 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.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-inherit.html" title="5.10. Inheritance">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.8. Row Security Policies </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 16.2 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.10. Inheritance</td></tr></table></div></body></html> \ No newline at end of file