summaryrefslogtreecommitdiffstats
path: root/doc/src/sgml/html/ddl-inherit.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/html/ddl-inherit.html')
-rw-r--r--doc/src/sgml/html/ddl-inherit.html289
1 files changed, 289 insertions, 0 deletions
diff --git a/doc/src/sgml/html/ddl-inherit.html b/doc/src/sgml/html/ddl-inherit.html
new file mode 100644
index 0000000..ec21492
--- /dev/null
+++ b/doc/src/sgml/html/ddl-inherit.html
@@ -0,0 +1,289 @@
+<?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.10. Inheritance</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-schemas.html" title="5.9. Schemas" /><link rel="next" href="ddl-partitioning.html" title="5.11. Table Partitioning" /></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.10. Inheritance</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-schemas.html" title="5.9. Schemas">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 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-partitioning.html" title="5.11. Table Partitioning">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-INHERIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.10. Inheritance</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ddl-inherit.html#DDL-INHERIT-CAVEATS">5.10.1. Caveats</a></span></dt></dl></div><a id="id-1.5.4.12.2" class="indexterm"></a><a id="id-1.5.4.12.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> 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 from the features described here.)
+ </p><p>
+ Let's start with an example: suppose we are trying to build a data
+ model for cities. Each state has many cities, but only one
+ capital. We want to be able to quickly retrieve the capital city
+ for any particular state. This can be done by creating two tables,
+ one for state capitals and one for cities that are not
+ capitals. However, what happens when we want to ask for data about
+ a city, regardless of whether it is a capital or not? The
+ inheritance feature can help to resolve this problem. We define the
+ <code class="structname">capitals</code> table so that it inherits from
+ <code class="structname">cities</code>:
+
+</p><pre class="programlisting">
+CREATE TABLE cities (
+ name text,
+ population float,
+ elevation int -- in feet
+);
+
+CREATE TABLE capitals (
+ state char(2)
+) INHERITS (cities);
+</pre><p>
+
+ In this case, the <code class="structname">capitals</code> table <em class="firstterm">inherits</em>
+ all the columns of its parent table, <code class="structname">cities</code>. State
+ capitals also have an extra column, <code class="structfield">state</code>, that shows
+ their state.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>, a table can inherit from
+ zero or more other tables, and a query can reference either all
+ rows of a table or all rows of a table plus all of its descendant tables.
+ The latter behavior is the default.
+ For example, the following query finds the names of all cities,
+ including state capitals, that are located at an elevation over
+ 500 feet:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM cities
+ WHERE elevation &gt; 500;
+</pre><p>
+
+ Given the sample data from the <span class="productname">PostgreSQL</span>
+ tutorial (see <a class="xref" href="tutorial-sql-intro.html" title="2.1. Introduction">Section 2.1</a>), this returns:
+
+</p><pre class="programlisting">
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+ Madison | 845
+</pre><p>
+ </p><p>
+ On the other hand, the following query finds all the cities that
+ are not state capitals and are situated at an elevation over 500 feet:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM ONLY cities
+ WHERE elevation &gt; 500;
+
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+</pre><p>
+ </p><p>
+ Here the <code class="literal">ONLY</code> keyword indicates that the query
+ should apply only to <code class="structname">cities</code>, and not any tables
+ below <code class="structname">cities</code> in the inheritance hierarchy. Many
+ of the commands that we have already discussed —
+ <code class="command">SELECT</code>, <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code> — support the
+ <code class="literal">ONLY</code> keyword.
+ </p><p>
+ You can also write the table name with a trailing <code class="literal">*</code>
+ to explicitly specify that descendant tables are included:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM cities*
+ WHERE elevation &gt; 500;
+</pre><p>
+
+ Writing <code class="literal">*</code> is not necessary, since this behavior is always
+ the default. However, this syntax is still supported for
+ compatibility with older releases where the default could be changed.
+ </p><p>
+ In some cases you might wish to know which table a particular row
+ originated from. There is a system column called
+ <code class="structfield">tableoid</code> in each table which can tell you the
+ originating table:
+
+</p><pre class="programlisting">
+SELECT c.tableoid, c.name, c.elevation
+FROM cities c
+WHERE c.elevation &gt; 500;
+</pre><p>
+
+ which returns:
+
+</p><pre class="programlisting">
+ tableoid | name | elevation
+----------+-----------+-----------
+ 139793 | Las Vegas | 2174
+ 139793 | Mariposa | 1953
+ 139798 | Madison | 845
+</pre><p>
+
+ (If you try to reproduce this example, you will probably get
+ different numeric OIDs.) By doing a join with
+ <code class="structname">pg_class</code> you can see the actual table names:
+
+</p><pre class="programlisting">
+SELECT p.relname, c.name, c.elevation
+FROM cities c, pg_class p
+WHERE c.elevation &gt; 500 AND c.tableoid = p.oid;
+</pre><p>
+
+ which returns:
+
+</p><pre class="programlisting">
+ relname | name | elevation
+----------+-----------+-----------
+ cities | Las Vegas | 2174
+ cities | Mariposa | 1953
+ capitals | Madison | 845
+</pre><p>
+ </p><p>
+ Another way to get the same effect is to use the <code class="type">regclass</code>
+ alias type, which will print the table OID symbolically:
+
+</p><pre class="programlisting">
+SELECT c.tableoid::regclass, c.name, c.elevation
+FROM cities c
+WHERE c.elevation &gt; 500;
+</pre><p>
+ </p><p>
+ Inheritance does not automatically propagate data from
+ <code class="command">INSERT</code> or <code class="command">COPY</code> commands to
+ other tables in the inheritance hierarchy. In our example, the
+ following <code class="command">INSERT</code> statement will fail:
+</p><pre class="programlisting">
+INSERT INTO cities (name, population, elevation, state)
+VALUES ('Albany', NULL, NULL, 'NY');
+</pre><p>
+ We might hope that the data would somehow be routed to the
+ <code class="structname">capitals</code> table, but this does not happen:
+ <code class="command">INSERT</code> always inserts into exactly the table
+ specified. In some cases it is possible to redirect the insertion
+ using a rule (see <a class="xref" href="rules.html" title="Chapter 41. The Rule System">Chapter 41</a>). However that does not
+ help for the above case because the <code class="structname">cities</code> table
+ does not contain the column <code class="structfield">state</code>, and so the
+ command will be rejected before the rule can be applied.
+ </p><p>
+ All check constraints and not-null constraints on a parent table are
+ automatically inherited by its children, unless explicitly specified
+ otherwise with <code class="literal">NO INHERIT</code> clauses. Other types of constraints
+ (unique, primary key, and foreign key constraints) are not inherited.
+ </p><p>
+ A table can inherit from more than one parent table, in which case it has
+ the union of the columns defined by the parent tables. Any columns
+ declared in the child table's definition are added to these. If the
+ same column name appears in multiple parent tables, or in both a parent
+ table and the child's definition, then these columns are <span class="quote">“<span class="quote">merged</span>”</span>
+ so that there is only one such column in the child table. To be merged,
+ columns must have the same data types, else an error is raised.
+ Inheritable check constraints and not-null constraints are merged in a
+ similar fashion. Thus, for example, a merged column will be marked
+ not-null if any one of the column definitions it came from is marked
+ not-null. Check constraints are merged if they have the same name,
+ and the merge will fail if their conditions are different.
+ </p><p>
+ Table inheritance is typically established when the child table is
+ created, using the <code class="literal">INHERITS</code> clause of the
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a>
+ statement.
+ Alternatively, a table which is already defined in a compatible way can
+ have a new parent relationship added, using the <code class="literal">INHERIT</code>
+ variant of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>.
+ To do this the new child table must already include columns with
+ the same names and types as the columns of the parent. It must also include
+ check constraints with the same names and check expressions as those of the
+ parent. Similarly an inheritance link can be removed from a child using the
+ <code class="literal">NO INHERIT</code> variant of <code class="command">ALTER TABLE</code>.
+ Dynamically adding and removing inheritance links like this can be useful
+ when the inheritance relationship is being used for table
+ partitioning (see <a class="xref" href="ddl-partitioning.html" title="5.11. Table Partitioning">Section 5.11</a>).
+ </p><p>
+ One convenient way to create a compatible table that will later be made
+ a new child is to use the <code class="literal">LIKE</code> clause in <code class="command">CREATE
+ TABLE</code>. This creates a new table with the same columns as
+ the source table. If there are any <code class="literal">CHECK</code>
+ constraints defined on the source table, the <code class="literal">INCLUDING
+ CONSTRAINTS</code> option to <code class="literal">LIKE</code> should be
+ specified, as the new child must have constraints matching the parent
+ to be considered compatible.
+ </p><p>
+ A parent table cannot be dropped while any of its children remain. Neither
+ can columns or check constraints of child tables be dropped or altered
+ if they are inherited
+ from any parent tables. If you wish to remove a table and all of its
+ descendants, one easy way is to drop the parent table with the
+ <code class="literal">CASCADE</code> option (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p><p>
+ <code class="command">ALTER TABLE</code> will
+ propagate any changes in column data definitions and check
+ constraints down the inheritance hierarchy. Again, dropping
+ columns that are depended on by other tables is only possible when using
+ the <code class="literal">CASCADE</code> option. <code class="command">ALTER
+ TABLE</code> follows the same rules for duplicate column merging
+ and rejection that apply during <code class="command">CREATE TABLE</code>.
+ </p><p>
+ Inherited queries perform access permission checks on the parent table
+ only. Thus, for example, granting <code class="literal">UPDATE</code> permission on
+ the <code class="structname">cities</code> table implies permission to update rows in
+ the <code class="structname">capitals</code> table as well, when they are
+ accessed through <code class="structname">cities</code>. This preserves the appearance
+ that the data is (also) in the parent table. But
+ the <code class="structname">capitals</code> table could not be updated directly
+ without an additional grant. In a similar way, the parent table's row
+ security policies (see <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a>) are applied to
+ rows coming from child tables during an inherited query. A child table's
+ policies, if any, are applied only when it is the table explicitly named
+ in the query; and in that case, any policies attached to its parent(s) are
+ ignored.
+ </p><p>
+ Foreign tables (see <a class="xref" href="ddl-foreign-data.html" title="5.12. Foreign Data">Section 5.12</a>) can also
+ be part of inheritance hierarchies, either as parent or child
+ tables, just as regular tables can be. If a foreign table is part
+ of an inheritance hierarchy then any operations not supported by
+ the foreign table are not supported on the whole hierarchy either.
+ </p><div class="sect2" id="DDL-INHERIT-CAVEATS"><div class="titlepage"><div><div><h3 class="title">5.10.1. Caveats</h3></div></div></div><p>
+ Note that not all SQL commands are able to work on
+ inheritance hierarchies. Commands that are used for data querying,
+ data modification, or schema modification
+ (e.g., <code class="literal">SELECT</code>, <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>,
+ most variants of <code class="literal">ALTER TABLE</code>, but
+ not <code class="literal">INSERT</code> or <code class="literal">ALTER TABLE ...
+ RENAME</code>) typically default to including child tables and
+ support the <code class="literal">ONLY</code> notation to exclude them.
+ Commands that do database maintenance and tuning
+ (e.g., <code class="literal">REINDEX</code>, <code class="literal">VACUUM</code>)
+ typically only work on individual, physical tables and do not
+ support recursing over inheritance hierarchies. The respective
+ behavior of each individual command is documented in its reference
+ page (<a class="xref" href="sql-commands.html" title="SQL Commands">SQL Commands</a>).
+ </p><p>
+ A serious limitation of the inheritance feature is that indexes (including
+ unique constraints) and foreign key constraints only apply to single
+ tables, not to their inheritance children. This is true on both the
+ referencing and referenced sides of a foreign key constraint. Thus,
+ in the terms of the above example:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If we declared <code class="structname">cities</code>.<code class="structfield">name</code> to be
+ <code class="literal">UNIQUE</code> or a <code class="literal">PRIMARY KEY</code>, this would not stop the
+ <code class="structname">capitals</code> table from having rows with names duplicating
+ rows in <code class="structname">cities</code>. And those duplicate rows would by
+ default show up in queries from <code class="structname">cities</code>. In fact, by
+ default <code class="structname">capitals</code> would have no unique constraint at all,
+ and so could contain multiple rows with the same name.
+ You could add a unique constraint to <code class="structname">capitals</code>, but this
+ would not prevent duplication compared to <code class="structname">cities</code>.
+ </p></li><li class="listitem"><p>
+ Similarly, if we were to specify that
+ <code class="structname">cities</code>.<code class="structfield">name</code> <code class="literal">REFERENCES</code> some
+ other table, this constraint would not automatically propagate to
+ <code class="structname">capitals</code>. In this case you could work around it by
+ manually adding the same <code class="literal">REFERENCES</code> constraint to
+ <code class="structname">capitals</code>.
+ </p></li><li class="listitem"><p>
+ Specifying that another table's column <code class="literal">REFERENCES
+ cities(name)</code> would allow the other table to contain city names, but
+ not capital names. There is no good workaround for this case.
+ </p></li></ul></div><p>
+
+ Some functionality not implemented for inheritance hierarchies is
+ implemented for declarative partitioning.
+ Considerable care is needed in deciding whether partitioning with legacy
+ inheritance is useful for your application.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-schemas.html" title="5.9. Schemas">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-partitioning.html" title="5.11. Table Partitioning">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.9. Schemas </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.11. Table Partitioning</td></tr></table></div></body></html> \ No newline at end of file