diff options
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/ddl.sgml | 223 | ||||
-rw-r--r-- | doc/src/sgml/ref/alter_table.sgml | 50 |
2 files changed, 211 insertions, 62 deletions
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index a6fb4b3691f..a404a9c6141 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.57 2006/04/30 21:15:32 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.58 2006/07/02 01:58:36 momjian Exp $ --> <chapter id="ddl"> <title>Data Definition</title> @@ -2061,27 +2061,47 @@ VALUES ('New York', NULL, NULL, 'NY'); </para> <para> - Table inheritance can currently only be defined using the <xref - linkend="sql-createtable" endterm="sql-createtable-title"> - statement. The related statement <command>CREATE TABLE AS</command> does - not allow inheritance to be specified. There - is no way to add an inheritance link to make an existing table into - a child table. Similarly, there is no way to remove an inheritance - link from a child table once it has been defined, other than by dropping - the table completely. A parent table cannot be dropped - while any of its children remain. If you wish to remove a table and - all of its descendants, one easy way is to drop the parent table with - the <literal>CASCADE</literal> option. + Table inheritance can be defined using the <xref linkend="sql-createtable" + endterm="sql-createtable-title"> statement using the + <command>INHERITS</command> keyword. However the related statement + <command>CREATE TABLE AS</command> does not allow inheritance to be + specified. + </para> + + <para> + Alternatively a table which is already defined in a compatible way can have + a new parent added with <xref linkend="sql-altertable" + endterm="sql-altertable-title"> using the <command>INHERIT</command> + subform. To do this the new child table must already include columns with + the same name and type as the columns of the parent. It must also include + check constraints with the same name and check expression as those of the + parent. Similarly an inheritance link can be removed from a child using the + <command>ALTER TABLE</command> using the <command>NO INHERIT</command> + subform. + + <para> + One convenient way to create a compatible table to be a new child is using + the <command>LIKE</command> option of <command>CREATE TABLE</command>. This + creates a table with the same columns with the same type (however note the + caveat below regarding constraints). Alternatively a compatible table can + be created by first creating a new child using <command>CREATE + TABLE</command> then removing the inheritance link with <command>ALTER + TABLE</command>. </para> + + <para> + A parent table cannot be dropped while any + of its children remain. If you wish to remove a table and all of its + descendants, one easy way is to drop the parent table with the + <literal>CASCADE</literal> option. Neither can columns of child tables be + dropped or altered if they are inherited from any parent tables. </para> <para> <xref linkend="sql-altertable" endterm="sql-altertable-title"> will - propagate any changes in column data definitions and check - constraints down the inheritance hierarchy. Again, dropping - columns or constraints on parent tables is only possible when using - the <literal>CASCADE</literal> option. <command>ALTER - TABLE</command> follows the same rules for duplicate column merging - and rejection that apply during <command>CREATE TABLE</command>. + propagate any changes in column data definitions and check constraints down + the inheritance hierarchy. <command>ALTER TABLE</command> follows the same + rules for duplicate column merging and rejection that apply during + <command>CREATE TABLE</command>. </para> <sect2 id="ddl-inherit-caveats"> @@ -2136,6 +2156,29 @@ VALUES ('New York', NULL, NULL, 'NY'); not capital names. There is no good workaround for this case. </para> </listitem> + + <listitem> + <para> + There is no convenient way to define a table compatible with a specific + parent including columns and constraints. The <command>LIKE</command> + option for <command>CREATE TABLE</command> does not copy constraints + which makes the tables it creates ineligible for being added using + <command>ALTER TABLE</command>. Matching check constraints must be added + manually or the table must be created as a child immediately, then if + needed removed from the inheritance structure temporarily to be added + again later. + </para> + </listitem> + + <listitem> + <para> + If a table is ever removed from the inheritance structure using + <command>ALTER TABLE</command> then all its columns will be marked as + being locally defined. This means <command>DROP COLUMN</command> on the + parent table will never cascade to drop those columns on the child + table. They must be dropped manually. + </para> + </listitem> </itemizedlist> These deficiencies will probably be fixed in some future release, @@ -2186,27 +2229,37 @@ VALUES ('New York', NULL, NULL, 'NY'); <itemizedlist> <listitem> <para> - Query performance can be improved dramatically for certain kinds - of queries. + Query performance can be improved when partition constraints can be + combined with local indexes to reduce the number of records that need to + be accessed for a query. Whereas the alternative, adding those columns + to every index, increases space usage which can erase any + performance gain. + <para> + + <para> + When most of the heavily accessed area of the table is in a single + partition or a small number of partitions. That partition and its + indexes are more likely to fit within memory than the index of the + entire table. </para> </listitem> <listitem> <para> - Update performance can be improved too, since each piece of the table - has indexes smaller than an index on the entire data set would be. - When an index no longer fits easily - in memory, both read and write operations on the index take - progressively more disk accesses. + When queries or updates access a large percentage of a a single + partition performance can be improved dramatically by taking advantage + of sequential disk access of a single partition instead of using an + index and random access reads across the whole table. </para> </listitem> <listitem> <para> - Bulk deletes may be accomplished by simply removing one of the - partitions, if that requirement is planned into the partitioning design. - <command>DROP TABLE</> is far faster than a bulk <command>DELETE</>, - to say nothing of the ensuing <command>VACUUM</> overhead. + Bulk loads and deletes may be accomplished by simply removing or adding + one of the partitions. <command>ALTER TABLE</> is far faster than a bulk + and takes the same amount of time regardless of the amount of data being + added or removed. It also entirely avoids the <command>VACUUM</command> + overhead caused by a bulk <command>delete</>. </para> </listitem> @@ -2404,12 +2457,12 @@ CREATE TABLE measurement ( Next we create one partition for each active month: <programlisting> -CREATE TABLE measurement_yy04mm02 ( ) INHERITS (measurement); -CREATE TABLE measurement_yy04mm03 ( ) INHERITS (measurement); +CREATE TABLE measurement_y2004m02 ( ) INHERITS (measurement); +CREATE TABLE measurement_y2004m03 ( ) INHERITS (measurement); ... -CREATE TABLE measurement_yy05mm11 ( ) INHERITS (measurement); -CREATE TABLE measurement_yy05mm12 ( ) INHERITS (measurement); -CREATE TABLE measurement_yy06mm01 ( ) INHERITS (measurement); +CREATE TABLE measurement_y2005m11 ( ) INHERITS (measurement); +CREATE TABLE measurement_y2005m12 ( ) INHERITS (measurement); +CREATE TABLE measurement_y2006m01 ( ) INHERITS (measurement); </programlisting> Each of the partitions are complete tables in their own right, @@ -2431,20 +2484,20 @@ CREATE TABLE measurement_yy06mm01 ( ) INHERITS (measurement); table creation script becomes: <programlisting> -CREATE TABLE measurement_yy04mm02 ( +CREATE TABLE measurement_y2004m02 ( CHECK ( logdate >= DATE '2004-02-01' AND logdate < DATE '2004-03-01' ) ) INHERITS (measurement); -CREATE TABLE measurement_yy04mm03 ( +CREATE TABLE measurement_y2004m03 ( CHECK ( logdate >= DATE '2004-03-01' AND logdate < DATE '2004-04-01' ) ) INHERITS (measurement); ... -CREATE TABLE measurement_yy05mm11 ( +CREATE TABLE measurement_y2005m11 ( CHECK ( logdate >= DATE '2005-11-01' AND logdate < DATE '2005-12-01' ) ) INHERITS (measurement); -CREATE TABLE measurement_yy05mm12 ( +CREATE TABLE measurement_y2005m12 ( CHECK ( logdate >= DATE '2005-12-01' AND logdate < DATE '2006-01-01' ) ) INHERITS (measurement); -CREATE TABLE measurement_yy06mm01 ( +CREATE TABLE measurement_y2006m01 ( CHECK ( logdate >= DATE '2006-01-01' AND logdate < DATE '2006-02-01' ) ) INHERITS (measurement); </programlisting> @@ -2456,12 +2509,12 @@ CREATE TABLE measurement_yy06mm01 ( We probably need indexes on the key columns too: <programlisting> -CREATE INDEX measurement_yy04mm02_logdate ON measurement_yy04mm02 (logdate); -CREATE INDEX measurement_yy04mm03_logdate ON measurement_yy04mm03 (logdate); +CREATE INDEX measurement_y2004m02_logdate ON measurement_y2004m02 (logdate); +CREATE INDEX measurement_y2004m03_logdate ON measurement_y2004m03 (logdate); ... -CREATE INDEX measurement_yy05mm11_logdate ON measurement_yy05mm11 (logdate); -CREATE INDEX measurement_yy05mm12_logdate ON measurement_yy05mm12 (logdate); -CREATE INDEX measurement_yy06mm01_logdate ON measurement_yy06mm01 (logdate); +CREATE INDEX measurement_y2005m11_logdate ON measurement_y2005m11 (logdate); +CREATE INDEX measurement_y2005m12_logdate ON measurement_y2005m12 (logdate); +CREATE INDEX measurement_y2006m01_logdate ON measurement_y2006m01 (logdate); </programlisting> We choose not to add further indexes at this time. @@ -2479,7 +2532,7 @@ CREATE INDEX measurement_yy06mm01_logdate ON measurement_yy06mm01 (logdate); CREATE OR REPLACE RULE measurement_current_partition AS ON INSERT TO measurement DO INSTEAD - INSERT INTO measurement_yy06mm01 VALUES ( NEW.city_id, + INSERT INTO measurement_y2006m01 VALUES ( NEW.city_id, NEW.logdate, NEW.peaktemp, NEW.unitsales ); @@ -2490,28 +2543,28 @@ DO INSTEAD could do this with a more complex set of rules as shown below. <programlisting> -CREATE RULE measurement_insert_yy04mm02 AS +CREATE RULE measurement_insert_y2004m02 AS ON INSERT TO measurement WHERE ( logdate >= DATE '2004-02-01' AND logdate < DATE '2004-03-01' ) DO INSTEAD - INSERT INTO measurement_yy04mm02 VALUES ( NEW.city_id, + INSERT INTO measurement_y2004m02 VALUES ( NEW.city_id, NEW.logdate, NEW.peaktemp, NEW.unitsales ); ... -CREATE RULE measurement_insert_yy05mm12 AS +CREATE RULE measurement_insert_y2005m12 AS ON INSERT TO measurement WHERE ( logdate >= DATE '2005-12-01' AND logdate < DATE '2006-01-01' ) DO INSTEAD - INSERT INTO measurement_yy05mm12 VALUES ( NEW.city_id, + INSERT INTO measurement_y2005m12 VALUES ( NEW.city_id, NEW.logdate, NEW.peaktemp, NEW.unitsales ); -CREATE RULE measurement_insert_yy06mm01 AS +CREATE RULE measurement_insert_y2006m01 AS ON INSERT TO measurement WHERE ( logdate >= DATE '2006-01-01' AND logdate < DATE '2006-02-01' ) DO INSTEAD - INSERT INTO measurement_yy06mm01 VALUES ( NEW.city_id, + INSERT INTO measurement_y2006m01 VALUES ( NEW.city_id, NEW.logdate, NEW.peaktemp, NEW.unitsales ); @@ -2522,6 +2575,44 @@ DO INSTEAD constraint for its partition. </para> </listitem> + + <listitem> + <para> + When the time comes to archive and remove the old data we first remove + it from the production table using: + +<programlisting> +ALTER TABLE measurement_y2003mm02 NO INHERIT measurement +</programlisting> + + Then we can perform any sort of data modification necessary prior to + archiving without impacting the data viewed by the production system. + This could include, for example, deleting or compressing out redundant + data. + </para> + </listitem> + <listitem> + <para> + + Similarly we can a new partition to handle new data. We can either + create an empty partition as the original partitions were created + above, or for some applications it's necessary to bulk load and clean + data for the new partition. If that operation involves multiple steps + by different processes it can be helpful to work with it in a fresh + table outside of the master partitioned table until it's ready to be + loaded: + +<programlisting> +CREATE TABLE measurement_y2006m02 (LIKE measurement WITH DEFAULTS); +\COPY measurement_y2006m02 FROM 'measurement_y2006m02' +UPDATE ... +ALTER TABLE measurement_y2006m02 ADD CONSTRAINT y2006m02 CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' ); +ALTER TABLE measurement_y2006m02 INHERIT MEASUREMENT; +</programlisting> + + </para> + </listitem> + </orderedlist> </para> @@ -2555,6 +2646,16 @@ DO INSTEAD using a set of rules as suggested above.) </para> </listitem> + + <listitem> + <para> + When using the <literal>LIKE</> option above to create new partitions + check constraints are not copied from the parent. If there are any check + constraints defined for the parent they must be manually created in new + partitions before <command>ALTER TABLE</command> will allow them to be + added. + </para> + </listitem> </itemizedlist> </para> @@ -2564,12 +2665,12 @@ DO INSTEAD <programlisting> CREATE VIEW measurement AS - SELECT * FROM measurement_yy04mm02 -UNION ALL SELECT * FROM measurement_yy04mm03 + SELECT * FROM measurement_y2004m02 +UNION ALL SELECT * FROM measurement_y2004m03 ... -UNION ALL SELECT * FROM measurement_yy05mm11 -UNION ALL SELECT * FROM measurement_yy05mm12 -UNION ALL SELECT * FROM measurement_yy06mm01; +UNION ALL SELECT * FROM measurement_y2005m11 +UNION ALL SELECT * FROM measurement_y2005m12 +UNION ALL SELECT * FROM measurement_y2006m01; </programlisting> However, the need to @@ -2619,14 +2720,14 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2006-01-01'; -> Append (cost=0.00..151.88 rows=2715 width=0) -> Seq Scan on measurement (cost=0.00..30.38 rows=543 width=0) Filter: (logdate >= '2006-01-01'::date) - -> Seq Scan on measurement_yy04mm02 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2004m02 measurement (cost=0.00..30.38 rows=543 width=0) Filter: (logdate >= '2006-01-01'::date) - -> Seq Scan on measurement_yy04mm03 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2004m03 measurement (cost=0.00..30.38 rows=543 width=0) Filter: (logdate >= '2006-01-01'::date) ... - -> Seq Scan on measurement_yy05mm12 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2005m12 measurement (cost=0.00..30.38 rows=543 width=0) Filter: (logdate >= '2006-01-01'::date) - -> Seq Scan on measurement_yy06mm01 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2006m01 measurement (cost=0.00..30.38 rows=543 width=0) Filter: (logdate >= '2006-01-01'::date) </programlisting> @@ -2645,7 +2746,7 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2006-01-01'; -> Append (cost=0.00..60.75 rows=1086 width=0) -> Seq Scan on measurement (cost=0.00..30.38 rows=543 width=0) Filter: (logdate >= '2006-01-01'::date) - -> Seq Scan on measurement_yy06mm01 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2006m01 measurement (cost=0.00..30.38 rows=543 width=0) Filter: (logdate >= '2006-01-01'::date) </programlisting> </para> diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 16f6ce8117a..ee501a1a372 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.84 2006/02/12 19:11:00 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.85 2006/07/02 01:58:36 momjian Exp $ PostgreSQL documentation --> @@ -46,6 +46,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: CLUSTER ON <replaceable class="PARAMETER">index_name</replaceable> SET WITHOUT CLUSTER SET WITHOUT OIDS + INHERIT <replaceable class="PARAMETER">parent_table</replaceable> + NO INHERIT <replaceable class="PARAMETER">parent_table</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable> SET TABLESPACE <replaceable class="PARAMETER">new_tablespace</replaceable> </synopsis> @@ -250,6 +252,52 @@ where <replaceable class="PARAMETER">action</replaceable> is one of: </varlistentry> <varlistentry> + <term><literal>INHERIT <replaceable class="PARAMETER">parent_table</replaceable></literal></term> + <listitem> + <para> + + This form adds a new parent table to the table. This won't add new + columns to the child table, instead all columns of the parent table must + already exist in the child table. They must have matching data types, + and if they have <literal>NOT NULL</literal> constraints in the parent + then they must also have <literal>NOT NULL</literal> constraints in the + child. + + </para> + <para> + + There must also be matching table constraints for all + <literal>CHECK</literal> table constraints of the parent. Currently + <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>, and + <literal>FOREIGN KEY</literal> constraints are ignored however this may + change in the future. + + </para> + <para> + + The easiest way to create a suitable table is to create a table using + <literal>INHERITS</literal> and then remove it via <literal>NO + INHERIT</literal>. Alternatively create a table using + <literal>LIKE</literal> however note that <literal>LIKE</literal> does + not create the necessary constraints. + + </para> + + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>NO INHERIT <replaceable class="PARAMETER">parent_table</replaceable></literal></term> + <listitem> + <para> + This form removes a parent table from the list of parents of the table. + Queries against the parent table will no longer include records drawn + from the target table. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><literal>OWNER</literal></term> <listitem> <para> |