gooderp18绿色标准版
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

295 lignes
18KB

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!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 V1.79.1" /><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><div xmlns="http://www.w3.org/TR/xhtml1/transitional" 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 12.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></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>
  3. <span class="productname">PostgreSQL</span> implements table inheritance,
  4. which can be a useful tool for database designers. (SQL:1999 and
  5. later define a type inheritance feature, which differs in many
  6. respects from the features described here.)
  7. </p><p>
  8. Let's start with an example: suppose we are trying to build a data
  9. model for cities. Each state has many cities, but only one
  10. capital. We want to be able to quickly retrieve the capital city
  11. for any particular state. This can be done by creating two tables,
  12. one for state capitals and one for cities that are not
  13. capitals. However, what happens when we want to ask for data about
  14. a city, regardless of whether it is a capital or not? The
  15. inheritance feature can help to resolve this problem. We define the
  16. <code class="structname">capitals</code> table so that it inherits from
  17. <code class="structname">cities</code>:
  18. </p><pre class="programlisting">
  19. CREATE TABLE cities (
  20. name text,
  21. population float,
  22. elevation int -- in feet
  23. );
  24. CREATE TABLE capitals (
  25. state char(2)
  26. ) INHERITS (cities);
  27. </pre><p>
  28. In this case, the <code class="structname">capitals</code> table <em class="firstterm">inherits</em>
  29. all the columns of its parent table, <code class="structname">cities</code>. State
  30. capitals also have an extra column, <code class="structfield">state</code>, that shows
  31. their state.
  32. </p><p>
  33. In <span class="productname">PostgreSQL</span>, a table can inherit from
  34. zero or more other tables, and a query can reference either all
  35. rows of a table or all rows of a table plus all of its descendant tables.
  36. The latter behavior is the default.
  37. For example, the following query finds the names of all cities,
  38. including state capitals, that are located at an elevation over
  39. 500 feet:
  40. </p><pre class="programlisting">
  41. SELECT name, elevation
  42. FROM cities
  43. WHERE elevation &gt; 500;
  44. </pre><p>
  45. Given the sample data from the <span class="productname">PostgreSQL</span>
  46. tutorial (see <a class="xref" href="tutorial-sql-intro.html" title="2.1. Introduction">Section 2.1</a>), this returns:
  47. </p><pre class="programlisting">
  48. name | elevation
  49. -----------+-----------
  50. Las Vegas | 2174
  51. Mariposa | 1953
  52. Madison | 845
  53. </pre><p>
  54. </p><p>
  55. On the other hand, the following query finds all the cities that
  56. are not state capitals and are situated at an elevation over 500 feet:
  57. </p><pre class="programlisting">
  58. SELECT name, elevation
  59. FROM ONLY cities
  60. WHERE elevation &gt; 500;
  61. name | elevation
  62. -----------+-----------
  63. Las Vegas | 2174
  64. Mariposa | 1953
  65. </pre><p>
  66. </p><p>
  67. Here the <code class="literal">ONLY</code> keyword indicates that the query
  68. should apply only to <code class="structname">cities</code>, and not any tables
  69. below <code class="structname">cities</code> in the inheritance hierarchy. Many
  70. of the commands that we have already discussed —
  71. <code class="command">SELECT</code>, <code class="command">UPDATE</code> and
  72. <code class="command">DELETE</code> — support the
  73. <code class="literal">ONLY</code> keyword.
  74. </p><p>
  75. You can also write the table name with a trailing <code class="literal">*</code>
  76. to explicitly specify that descendant tables are included:
  77. </p><pre class="programlisting">
  78. SELECT name, elevation
  79. FROM cities*
  80. WHERE elevation &gt; 500;
  81. </pre><p>
  82. Writing <code class="literal">*</code> is not necessary, since this behavior is always
  83. the default. However, this syntax is still supported for
  84. compatibility with older releases where the default could be changed.
  85. </p><p>
  86. In some cases you might wish to know which table a particular row
  87. originated from. There is a system column called
  88. <code class="structfield">tableoid</code> in each table which can tell you the
  89. originating table:
  90. </p><pre class="programlisting">
  91. SELECT c.tableoid, c.name, c.elevation
  92. FROM cities c
  93. WHERE c.elevation &gt; 500;
  94. </pre><p>
  95. which returns:
  96. </p><pre class="programlisting">
  97. tableoid | name | elevation
  98. ----------+-----------+-----------
  99. 139793 | Las Vegas | 2174
  100. 139793 | Mariposa | 1953
  101. 139798 | Madison | 845
  102. </pre><p>
  103. (If you try to reproduce this example, you will probably get
  104. different numeric OIDs.) By doing a join with
  105. <code class="structname">pg_class</code> you can see the actual table names:
  106. </p><pre class="programlisting">
  107. SELECT p.relname, c.name, c.elevation
  108. FROM cities c, pg_class p
  109. WHERE c.elevation &gt; 500 AND c.tableoid = p.oid;
  110. </pre><p>
  111. which returns:
  112. </p><pre class="programlisting">
  113. relname | name | elevation
  114. ----------+-----------+-----------
  115. cities | Las Vegas | 2174
  116. cities | Mariposa | 1953
  117. capitals | Madison | 845
  118. </pre><p>
  119. </p><p>
  120. Another way to get the same effect is to use the <code class="type">regclass</code>
  121. alias type, which will print the table OID symbolically:
  122. </p><pre class="programlisting">
  123. SELECT c.tableoid::regclass, c.name, c.elevation
  124. FROM cities c
  125. WHERE c.elevation &gt; 500;
  126. </pre><p>
  127. </p><p>
  128. Inheritance does not automatically propagate data from
  129. <code class="command">INSERT</code> or <code class="command">COPY</code> commands to
  130. other tables in the inheritance hierarchy. In our example, the
  131. following <code class="command">INSERT</code> statement will fail:
  132. </p><pre class="programlisting">
  133. INSERT INTO cities (name, population, elevation, state)
  134. VALUES ('Albany', NULL, NULL, 'NY');
  135. </pre><p>
  136. We might hope that the data would somehow be routed to the
  137. <code class="structname">capitals</code> table, but this does not happen:
  138. <code class="command">INSERT</code> always inserts into exactly the table
  139. specified. In some cases it is possible to redirect the insertion
  140. using a rule (see <a class="xref" href="rules.html" title="Chapter 40. The Rule System">Chapter 40</a>). However that does not
  141. help for the above case because the <code class="structname">cities</code> table
  142. does not contain the column <code class="structfield">state</code>, and so the
  143. command will be rejected before the rule can be applied.
  144. </p><p>
  145. All check constraints and not-null constraints on a parent table are
  146. automatically inherited by its children, unless explicitly specified
  147. otherwise with <code class="literal">NO INHERIT</code> clauses. Other types of constraints
  148. (unique, primary key, and foreign key constraints) are not inherited.
  149. </p><p>
  150. A table can inherit from more than one parent table, in which case it has
  151. the union of the columns defined by the parent tables. Any columns
  152. declared in the child table's definition are added to these. If the
  153. same column name appears in multiple parent tables, or in both a parent
  154. table and the child's definition, then these columns are <span class="quote">“<span class="quote">merged</span>”</span>
  155. so that there is only one such column in the child table. To be merged,
  156. columns must have the same data types, else an error is raised.
  157. Inheritable check constraints and not-null constraints are merged in a
  158. similar fashion. Thus, for example, a merged column will be marked
  159. not-null if any one of the column definitions it came from is marked
  160. not-null. Check constraints are merged if they have the same name,
  161. and the merge will fail if their conditions are different.
  162. </p><p>
  163. Table inheritance is typically established when the child table is
  164. created, using the <code class="literal">INHERITS</code> clause of the
  165. <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>
  166. statement.
  167. Alternatively, a table which is already defined in a compatible way can
  168. have a new parent relationship added, using the <code class="literal">INHERIT</code>
  169. variant of <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a>.
  170. To do this the new child table must already include columns with
  171. the same names and types as the columns of the parent. It must also include
  172. check constraints with the same names and check expressions as those of the
  173. parent. Similarly an inheritance link can be removed from a child using the
  174. <code class="literal">NO INHERIT</code> variant of <code class="command">ALTER TABLE</code>.
  175. Dynamically adding and removing inheritance links like this can be useful
  176. when the inheritance relationship is being used for table
  177. partitioning (see <a class="xref" href="ddl-partitioning.html" title="5.11. Table Partitioning">Section 5.11</a>).
  178. </p><p>
  179. One convenient way to create a compatible table that will later be made
  180. a new child is to use the <code class="literal">LIKE</code> clause in <code class="command">CREATE
  181. TABLE</code>. This creates a new table with the same columns as
  182. the source table. If there are any <code class="literal">CHECK</code>
  183. constraints defined on the source table, the <code class="literal">INCLUDING
  184. CONSTRAINTS</code> option to <code class="literal">LIKE</code> should be
  185. specified, as the new child must have constraints matching the parent
  186. to be considered compatible.
  187. </p><p>
  188. A parent table cannot be dropped while any of its children remain. Neither
  189. can columns or check constraints of child tables be dropped or altered
  190. if they are inherited
  191. from any parent tables. If you wish to remove a table and all of its
  192. descendants, one easy way is to drop the parent table with the
  193. <code class="literal">CASCADE</code> option (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
  194. </p><p>
  195. <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a> will
  196. propagate any changes in column data definitions and check
  197. constraints down the inheritance hierarchy. Again, dropping
  198. columns that are depended on by other tables is only possible when using
  199. the <code class="literal">CASCADE</code> option. <code class="command">ALTER
  200. TABLE</code> follows the same rules for duplicate column merging
  201. and rejection that apply during <code class="command">CREATE TABLE</code>.
  202. </p><p>
  203. Inherited queries perform access permission checks on the parent table
  204. only. Thus, for example, granting <code class="literal">UPDATE</code> permission on
  205. the <code class="structname">cities</code> table implies permission to update rows in
  206. the <code class="structname">capitals</code> table as well, when they are
  207. accessed through <code class="structname">cities</code>. This preserves the appearance
  208. that the data is (also) in the parent table. But
  209. the <code class="structname">capitals</code> table could not be updated directly
  210. without an additional grant. Two exceptions to this rule are
  211. <code class="command">TRUNCATE</code> and <code class="command">LOCK TABLE</code>,
  212. where permissions on the child tables are always checked,
  213. whether they are processed directly or recursively via those commands
  214. performed on the parent table.
  215. </p><p>
  216. In a similar way, the parent table's row
  217. security policies (see <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a>) are applied to
  218. rows coming from child tables during an inherited query. A child table's
  219. policies, if any, are applied only when it is the table explicitly named
  220. in the query; and in that case, any policies attached to its parent(s) are
  221. ignored.
  222. </p><p>
  223. Foreign tables (see <a class="xref" href="ddl-foreign-data.html" title="5.12. Foreign Data">Section 5.12</a>) can also
  224. be part of inheritance hierarchies, either as parent or child
  225. tables, just as regular tables can be. If a foreign table is part
  226. of an inheritance hierarchy then any operations not supported by
  227. the foreign table are not supported on the whole hierarchy either.
  228. </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>
  229. Note that not all SQL commands are able to work on
  230. inheritance hierarchies. Commands that are used for data querying,
  231. data modification, or schema modification
  232. (e.g., <code class="literal">SELECT</code>, <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>,
  233. most variants of <code class="literal">ALTER TABLE</code>, but
  234. not <code class="literal">INSERT</code> or <code class="literal">ALTER TABLE ...
  235. RENAME</code>) typically default to including child tables and
  236. support the <code class="literal">ONLY</code> notation to exclude them.
  237. Commands that do database maintenance and tuning
  238. (e.g., <code class="literal">REINDEX</code>, <code class="literal">VACUUM</code>)
  239. typically only work on individual, physical tables and do not
  240. support recursing over inheritance hierarchies. The respective
  241. behavior of each individual command is documented in its reference
  242. page (<a class="xref" href="sql-commands.html" title="SQL Commands">SQL Commands</a>).
  243. </p><p>
  244. A serious limitation of the inheritance feature is that indexes (including
  245. unique constraints) and foreign key constraints only apply to single
  246. tables, not to their inheritance children. This is true on both the
  247. referencing and referenced sides of a foreign key constraint. Thus,
  248. in the terms of the above example:
  249. </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
  250. If we declared <code class="structname">cities</code>.<code class="structfield">name</code> to be
  251. <code class="literal">UNIQUE</code> or a <code class="literal">PRIMARY KEY</code>, this would not stop the
  252. <code class="structname">capitals</code> table from having rows with names duplicating
  253. rows in <code class="structname">cities</code>. And those duplicate rows would by
  254. default show up in queries from <code class="structname">cities</code>. In fact, by
  255. default <code class="structname">capitals</code> would have no unique constraint at all,
  256. and so could contain multiple rows with the same name.
  257. You could add a unique constraint to <code class="structname">capitals</code>, but this
  258. would not prevent duplication compared to <code class="structname">cities</code>.
  259. </p></li><li class="listitem"><p>
  260. Similarly, if we were to specify that
  261. <code class="structname">cities</code>.<code class="structfield">name</code> <code class="literal">REFERENCES</code> some
  262. other table, this constraint would not automatically propagate to
  263. <code class="structname">capitals</code>. In this case you could work around it by
  264. manually adding the same <code class="literal">REFERENCES</code> constraint to
  265. <code class="structname">capitals</code>.
  266. </p></li><li class="listitem"><p>
  267. Specifying that another table's column <code class="literal">REFERENCES
  268. cities(name)</code> would allow the other table to contain city names, but
  269. not capital names. There is no good workaround for this case.
  270. </p></li></ul></div><p>
  271. Some functionality not implemented for inheritance hierarchies is
  272. implemented for declarative partitioning.
  273. Considerable care is needed in deciding whether partitioning with legacy
  274. inheritance is useful for your application.
  275. </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">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-partitioning.html">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">Home</a></td><td width="40%" align="right" valign="top"> 5.11. Table Partitioning</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1