<literal>pg_catalog</literal>.
</para>
<!-- "DROP SCHEMA public" is inferior to this REVOKE, because pg_dump
doesn't preserve that DROP. -->
</listitem>
<listitem>
<para>
Remove the public schema from the default search path, by modifying
<link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>
or by issuing <literal>ALTER ROLE ALL SET search_path =
"$user"</literal>. 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 <link linkend="typeconv-func">will be unsafe or
unreliable</link>. 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 <literal>ADMIN OPTION</literal> on a relevant role.
</para>
</listitem>
<listitem>
<para>
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 <productname>PostgreSQL</productname> 14 or earlier, this is the
default.
</para>
</listitem>
</itemizedlist>
</para>
<para>
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.
</para>
</sect2>
<sect2 id="ddl-schemas-portability">
<title>Portability</title>
<para>
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
<literal><replaceable>user_name</replaceable>.<replaceable>table_name</replaceable></literal>.
This is how <productname>PostgreSQL</productname> will effectively
behave if you create a per-user schema for every user.
</para>
<para>
Also, there is no concept of a <literal>public</literal> schema in the
SQL standard. For maximum conformance to the standard, you should
not use the <literal>public</literal> schema.
</para>
<para>
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.
</para>
</sect2>
</sect1>
<sect1 id="ddl-inherit">
<title>Inheritance</title>
<indexterm>
<primary>inheritance</primary>
</indexterm>
<indexterm>
<primary>table</primary>
<secondary>inheritance</secondary>
</indexterm>
<para>
<productname>PostgreSQL</productname> implements table inheritance,
which can be a useful tool for database designers. (SQL:1999 and
later define a type inheritance feature, which differs in many
respects