CREATE TABLE PARTITION creates a partitioned table. Partitioning refers to splitting what is logically one large table into smaller physical pieces based on specific schemes. The table based on the logic is called a partition cable, and a physical piece is called a partition. Data is stored on these smaller physical pieces, namely, partitions, instead of the larger logical partitioned table.
The common forms of partitioning include range partitioning, hash partitioning, list partitioning, and value partitioning. Currently, row-store and column-store tables support only range partitioning.
In range partitioning, the table is partitioned into ranges defined by a key column or set of columns, with no overlap between the ranges of values assigned to different partitions. Each range has a dedicated partition for data storage.
The partitioning policy for Range Partitioning refers to how data is inserted into partitions. Currently, range partitioning only allows the use of the range partitioning policy.
Range partitioning policy: Data is mapped to a created partition based on the partition key value. If the data can be mapped to, it is inserted into the specific partition; if it cannot be mapped to, error messages are returned. This is the most commonly used partitioning policy.
Partitioning can provide several benefits:
A partitioned table supports unique and primary key constraints. The constraint keys of these constraints contain all partition keys.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | CREATE TABLE [ IF NOT EXISTS ] partition_table_name ( [ { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option [...] ] }[, ... ] ] ) [ WITH ( {storage_parameter = value} [, ... ] ) ] [ COMPRESS | NOCOMPRESS ] [ TABLESPACE tablespace_name ] [ DISTRIBUTE BY { REPLICATION | { [ HASH ] ( column_name ) } } ] [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ] PARTITION BY { {VALUES (partition_key)} | {RANGE (partition_key) ( partition_less_than_item [, ... ] )} | {RANGE (partition_key) ( partition_start_end_item [, ... ] )} } [ { ENABLE | DISABLE } ROW MOVEMENT ]; |
1 2 3 4 5 6 7 8 | [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | UNIQUE index_parameters | PRIMARY KEY index_parameters } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] |
[ CONSTRAINT constraint_name ] { CHECK ( expression ) | UNIQUE ( column_name [, ... ] ) index_parameters | PRIMARY KEY ( column_name [, ... ] ) index_parameters} [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
1 | { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS | DISTRIBUTION | ALL } |
1 2 | [ WITH ( {storage_parameter = value} [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] |
1 | PARTITION partition_name VALUES LESS THAN ( { partition_value | MAXVALUE } ) [TABLESPACE tablespace_name] |
1 2 3 4 5 6 | PARTITION partition_name { {START(partition_value) END (partition_value) EVERY (interval_value)} | {START(partition_value) END ({partition_value | MAXVALUE})} | {START(partition_value)} | {END({partition_value | MAXVALUE})} } [TABLESPACE tablespace_name] |
Does not throw an error if a table with the same name exists. A notice is issued in this case.
Name of the partitioned table
Value range: a string. It must comply with the naming convention.
Specifies the name of a column to be created in the new table.
Value range: a string. It must comply with the naming convention.
Specifies the data type of the column.
Assigns a collation to the column (which must be of a collatable data type). If no collation is specified, the default collation is used.
The collatable types are char, varchar, text, nchar, and nvarchar.
Specifies a name for a column or table constraint. The optional constraint clauses specify constraints that new or updated rows must satisfy for an insert or update operation to succeed.
There are two ways to define constraints:
Specifies a table from which the new table automatically copies all column names, their data types, and their not-null constraints.
Unlike INHERITS, the new table and original table are decoupled after creation is complete. Changes to the original table will not be applied to the new table, and it is not possible to include data of the new table in scans of the original table.
Default expressions for the copied column definitions will only be copied if INCLUDING DEFAULTS is specified. The default behavior is to exclude default expressions, resulting in the copied columns in the new table having default values NULL.
NOT NULL constraints are always copied to the new table. CHECK constraints will only be copied if INCLUDING CONSTRAINTS is specified; other types of constraints will never be copied. These rules also apply to column constraints and table constraints.
Unlike INHERITS, columns and constraints copied by LIKE are not merged with similarly named columns and constraints. If the same name is specified explicitly or in another LIKE clause, an error is reported.
Specifies an optional storage parameter for a table or an index. Optional parameters are as follows:
The fillfactor of a table is a percentage between 10 and 100. 100 (complete packing) is the default value. When a smaller fillfactor is specified, INSERT operations pack table pages only to the indicated percentage. The remaining space on each page is reserved for updating rows on that page. This gives UPDATE a chance to place the updated copy of a row on the same page, which is more efficient than placing it on a different page. For a table whose records are never updated, setting the fillfactor to 100 (complete packing) is the appropriate choice, but in heavily updated tables smaller fillfactors are appropriate. The parameter has no meaning for column-store tables.
Value range: 10–100
Determines the storage mode of the data in the table.
Valid value:
orientation cannot be modified.
The row-store table compression function is not put into commercial use. To use this function, contact technical support engineers.
Specifies the maximum of a storage unit during data loading process. The parameter is only valid for column-store table.
Value range: 10000 to 60000
Default value: 60000
Specifies the number of records to be partial cluster stored during data loading process. The parameter is only valid for column-store table.
Value range: The valid value is no less than 100000. The value is the multiple of MAX_BATCHROW.
Specifies whether to enable delta tables in column-store tables. The parameter is only valid for column-store tables.
Default value: off
A reserved parameter. The parameter is only valid for column-store table.
The value ranges from 0 to 60000. The default value is 6000.
Specifies the OBS tablespace for the cold partitions in a hot or cold table. This parameter is available only to partitioned column-store tables and cannot be modified. It must be used together with storage_policy.
Valid value: a valid OBS tablespace name
Specifies the rule for switching between hot and cold partitions. This parameter is used only for multi-temperature tables. It must be used together with cold_tablespace.
Value range: Cold and hot switchover policy name:Cold and hot switchover threshold. Currently, only LMT and HPN policies are supported. LMT indicates that the switchover is performed based on the last update time of partitions. HPN indicates the switchover is performed based on a fixed number of reserved hot partitions.
Specifies the version of the column-store format. Switching between different storage formats is supported. However, the storage format of a partitioned table cannot be switched.
Valid value:
1.0: Each column in a column-store table is stored in a separate file. The file name is relfilenode.C1.0, relfilenode.C2.0, relfilenode.C3.0, or similar.
2.0: All columns of a column-store table are combined and stored in a file. The file is named relfilenode.C1.0.
Default value: 2.0
The value of COLVERSION can only be set to 2.0 for OBS hot and cold tables.
When creating a column-store table, set COLVERSION to 2.0. Compared with the 1.0 storage format, the performance is significantly improved:
Indicates whether to skip the hint bits operation when the full-page writes (FPW) log needs to be written during sequential scanning.
If SKIP_FPI_HINT is set to true and the checkpoint operation is performed on a table, no Xlog will be generated when the table is sequentially scanned. This applies to intermediate tables that are queried less frequently, reducing the size of Xlogs and improving query performance.
Specifies the keyword COMPRESS during the creation of a table, so that the compression feature is triggered in the case of a bulk INSERT operation. If this feature is enabled, a scan is performed for all tuple data within the page to generate a dictionary and then the tuple data is compressed and stored. If NOCOMPRESS is specified, the table is not compressed.
Default value: NOCOMPRESS, tuple data is not compressed before storage.
Specifies the new table will be created in tablespace_name tablespace. If not specified, default tablespace is used. The OBS tablespace is not supported.
Specifies how the table is distributed or replicated between DNs.
Valid value:
Default value: HASH(column_name), the key column of column_name (if any) or the column of distribution column supported by first data type.
column_name supports the following data types:
TO GROUP specifies the Node Group in which the table is created. Currently, it cannot be used for HDFS tables. TO NODE is used for internal scale-out tools.
Creates a range partition. partition_key is the name of the partition key.
(1) Assume that the VALUES LESS THAN syntax is used.
In this case, a maximum of four partition keys are supported.
Data types supported by the partition keys are as follows: SMALLINT, INTEGER, BIGINT, DECIMAL, NUMERIC, REAL, DOUBLE PRECISION, CHARACTER VARYING(n), VARCHAR(n), CHARACTER(n), CHAR(n), CHARACTER, CHAR, TEXT, NVARCHAR2, NAME, TIMESTAMP[(p)] [WITHOUT TIME ZONE], TIMESTAMP[(p)] [WITH TIME ZONE], and DATE.
(2) Assume that the START END syntax is used.
In this case, only one partition key is supported.
Data types supported by the partition key are as follows: SMALLINT, INTEGER, BIGINT, DECIMAL, NUMERIC, REAL, DOUBLE PRECISION, TIMESTAMP[(p)] [WITHOUT TIME ZONE], TIMESTAMP[(p)] [WITH TIME ZONE], and DATE.
Specifies the information of partitions. partition_name is the name of a range partition. partition_value is the upper limit of range partition, and the value depends on the type of partition_key. MAXVALUE can specify the upper boundary of a range partition, and it is commonly used to specify the upper boundary of the last range partition.
Specifies partition definitions.
Specifies the row movement switch.
If the tuple value is updated on the partition key during the UPDATE action, the partition where the tuple is located is altered. Setting of this parameter enables error messages to be reported or movement of the tuple between partitions.
Valid value:
Indicates that the column is not allowed to contain NULL values. ENABLE can be omitted.
Indicates that the column is allowed to contain NULL values. This is the default setting.
This clause is only provided for compatibility with non-standard SQL databases. You are advised not to use this clause.
Specifies an expression producing a Boolean result which new or updated rows must satisfy for an insert or update operation to succeed. Expressions evaluating to TRUE or UNKNOWN succeed. If any row of an insert or update operation produces a FALSE result, an error exception is raised and the insert or update does not alter the database.
A check constraint specified as a column constraint should reference only the column's values, while an expression appearing in a table constraint can reference multiple columns.
A constraint marked with NO INHERIT will not propagate to child tables.
ENABLE can be omitted.
Assigns a default data value for a column. The value can be any variable-free expressions (Subqueries and cross-references to other columns in the current table are not allowed). The data type of the default expression must match the data type of the column.
The default expression will be used in any insert operation that does not specify a value for the column. If there is no default value for a column, then the default value is NULL.
UNIQUE ( column_name [, ... ] ) index_parameters
Specifies that a group of one or more columns of a table can contain only unique values.
For the purpose of a unique constraint, NULL is not considered equal.
If DISTRIBUTE BY REPLICATION is not specified, the column table that contains only unique values must contain distribution columns.
PRIMARY KEY ( column_name [, ... ] ) index_parameters
Specifies the primary key constraint specifies that a column or columns of a table can contain only unique (non-duplicate) and non-null values.
Only one primary key can be specified for a table.
If DISTRIBUTE BY REPLICATION is not specified, the column set with a primary key constraint must contain distributed columns.
Controls whether the constraint can be deferred. A constraint that is not deferrable will be checked immediately after every command. Checking of constraints that are deferrable can be postponed until the end of the transaction using the SET CONSTRAINTS command. NOT DEFERRABLE is the default value. Currently, only UNIQUE and PRIMARY KEY constraints of row-store tables accept this clause. All the other constraints are not deferrable.
If a constraint is deferrable, this clause specifies the default time to check the constraint.
The constraint check time can be altered using the SET CONSTRAINTS command.
Allows selection of the tablespace in which the index associated with a UNIQUE or PRIMARY KEY constraint will be created. If not specified, default_tablespace is consulted, or the default tablespace in the database if default_tablespace is empty. The OBS tablespace is not supported.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | CREATE TABLE tpcds.web_returns_p1 ( WR_RETURNED_DATE_SK INTEGER , WR_RETURNED_TIME_SK INTEGER , WR_ITEM_SK INTEGER NOT NULL, WR_REFUNDED_CUSTOMER_SK INTEGER , WR_REFUNDED_CDEMO_SK INTEGER , WR_REFUNDED_HDEMO_SK INTEGER , WR_REFUNDED_ADDR_SK INTEGER , WR_RETURNING_CUSTOMER_SK INTEGER , WR_RETURNING_CDEMO_SK INTEGER , WR_RETURNING_HDEMO_SK INTEGER , WR_RETURNING_ADDR_SK INTEGER , WR_WEB_PAGE_SK INTEGER , WR_REASON_SK INTEGER , WR_ORDER_NUMBER BIGINT NOT NULL, WR_RETURN_QUANTITY INTEGER , WR_RETURN_AMT DECIMAL(7,2) , WR_RETURN_TAX DECIMAL(7,2) , WR_RETURN_AMT_INC_TAX DECIMAL(7,2) , WR_FEE DECIMAL(7,2) , WR_RETURN_SHIP_COST DECIMAL(7,2) , WR_REFUNDED_CASH DECIMAL(7,2) , WR_REVERSED_CHARGE DECIMAL(7,2) , WR_ACCOUNT_CREDIT DECIMAL(7,2) , WR_NET_LOSS DECIMAL(7,2) ) WITH (ORIENTATION = COLUMN,COMPRESSION=MIDDLE) DISTRIBUTE BY HASH (WR_ITEM_SK) PARTITION BY RANGE(WR_RETURNED_DATE_SK) ( PARTITION P1 VALUES LESS THAN(2450815), PARTITION P2 VALUES LESS THAN(2451179), PARTITION P3 VALUES LESS THAN(2451544), PARTITION P4 VALUES LESS THAN(2451910), PARTITION P5 VALUES LESS THAN(2452275), PARTITION P6 VALUES LESS THAN(2452640), PARTITION P7 VALUES LESS THAN(2453005), PARTITION P8 VALUES LESS THAN(MAXVALUE) ); |
The ranges of the partitions are: wr_returned_date_sk < 2450815, 2450815 ≤ wr_returned_date_sk < 2451179, 2451179 ≤ wr_returned_date_sk < 2451544, 2451544 ≤ wr_returned_date_sk < 2451910, 2451910 ≤ wr_returned_date_sk < 2452275, 2452275 ≤ wr_returned_date_sk < 2452640, 2452640 ≤ wr_returned_date_sk < 2453005, and wr_returned_date_sk ≥ 2453005.
Assume that CN and DN data directory/pg_location/mount1/path1, CN and DN data directory/pg_location/mount2/path2, CN and DN data directory/pg_location/mount3/path3, and CN and DN data directory/pg_location/mount4/path4 are empty directories for which user dwsadmin has read and write permissions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | CREATE TABLE tpcds.web_returns_p2 ( WR_RETURNED_DATE_SK INTEGER , WR_RETURNED_TIME_SK INTEGER , WR_ITEM_SK INTEGER NOT NULL, WR_REFUNDED_CUSTOMER_SK INTEGER , WR_REFUNDED_CDEMO_SK INTEGER , WR_REFUNDED_HDEMO_SK INTEGER , WR_REFUNDED_ADDR_SK INTEGER , WR_RETURNING_CUSTOMER_SK INTEGER , WR_RETURNING_CDEMO_SK INTEGER , WR_RETURNING_HDEMO_SK INTEGER , WR_RETURNING_ADDR_SK INTEGER , WR_WEB_PAGE_SK INTEGER , WR_REASON_SK INTEGER , WR_ORDER_NUMBER BIGINT NOT NULL, WR_RETURN_QUANTITY INTEGER , WR_RETURN_AMT DECIMAL(7,2) , WR_RETURN_TAX DECIMAL(7,2) , WR_RETURN_AMT_INC_TAX DECIMAL(7,2) , WR_FEE DECIMAL(7,2) , WR_RETURN_SHIP_COST DECIMAL(7,2) , WR_REFUNDED_CASH DECIMAL(7,2) , WR_REVERSED_CHARGE DECIMAL(7,2) , WR_ACCOUNT_CREDIT DECIMAL(7,2) , WR_NET_LOSS DECIMAL(7,2) ) DISTRIBUTE BY HASH (WR_ITEM_SK) PARTITION BY RANGE(WR_RETURNED_DATE_SK) ( PARTITION P1 VALUES LESS THAN(2450815), PARTITION P2 VALUES LESS THAN(2451179), PARTITION P3 VALUES LESS THAN(2451544), PARTITION P4 VALUES LESS THAN(2451910), PARTITION P5 VALUES LESS THAN(2452275), PARTITION P6 VALUES LESS THAN(2452640), PARTITION P7 VALUES LESS THAN(2453005), PARTITION P8 VALUES LESS THAN(MAXVALUE) ) ENABLE ROW MOVEMENT; |
Assume that /home/dbadmin/startend_tbs1, /home/dbadmin/startend_tbs2, /home/dbadmin/startend_tbs3, and /home/dbadmin/startend_tbs4 are empty directories that user dbadmin has read and write permissions for.
Create a partitioned table with the partition key of type integer.
1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE tpcds.startend_pt (c1 INT, c2 INT) DISTRIBUTE BY HASH (c1) PARTITION BY RANGE (c2) ( PARTITION p1 START(1) END(1000) EVERY(200) , PARTITION p2 END(2000), PARTITION p3 START(2000) END(2500) , PARTITION p4 START(2500), PARTITION p5 START(3000) END(5000) EVERY(1000) ) ENABLE ROW MOVEMENT; |
View the information of the partitioned table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | SELECT relname, boundaries FROM pg_partition p where p.parentid='tpcds.startend_pt'::regclass ORDER BY 1; relname | boundaries -------------+------------ p1_0 | {1} p1_1 | {201} p1_2 | {401} p1_3 | {601} p1_4 | {801} p1_5 | {1000} p2 | {2000} p3 | {2500} p4 | {3000} p5_1 | {4000} p5_2 | {5000} tpcds.startend_pt | (12 rows) |
Import data and check the data volume in the partition.
1 2 3 4 5 6 7 8 9 10 11 12 | INSERT INTO tpcds.startend_pt VALUES (GENERATE_SERIES(0, 4999), GENERATE_SERIES(0, 4999)); SELECT COUNT(*) FROM tpcds.startend_pt PARTITION FOR (0); count ------- 1 (1 row) SELECT COUNT(*) FROM tpcds.startend_pt PARTITION (p3); count ------- 500 (1 row) |
View the information of the partitioned table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | SELECT relname, boundaries FROM pg_partition p where p.parentid='tpcds.startend_pt'::regclass ORDER BY 1; relname | boundaries -------------+------------ p1_0 | {1} p1_1 | {201} p1_2 | {401} p1_3 | {601} p1_4 | {801} p1_5 | {1000} p2 | {2000} p3 | {2500} p4 | {3000} p5_1 | {4000} p6_1 | {5300} p6_2 | {5600} p6_3 | {5900} p71 | {6000} q1_1 | {4250} q1_2 | {4500} q1_3 | {4750} q1_4 | {5000} tpcds.startend_pt | (19 rows) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | CREATE TABLE customer_address ( ca_address_sk integer NOT NULL, ca_address_date date NOT NULL ) DISTRIBUTE BY HASH (ca_address_sk) PARTITION BY RANGE (ca_address_date) ( PARTITION p202001 VALUES LESS THAN('20200101'), PARTITION p202002 VALUES LESS THAN('20200201'), PARTITION p202003 VALUES LESS THAN('20200301'), PARTITION p202004 VALUES LESS THAN('20200401'), PARTITION p202005 VALUES LESS THAN('20200501'), PARTITION p202006 VALUES LESS THAN('20200601'), PARTITION p202007 VALUES LESS THAN('20200701'), PARTITION p202008 VALUES LESS THAN('20200801'), PARTITION p202009 VALUES LESS THAN('20200901'), PARTITION p202010 VALUES LESS THAN('20201001'), PARTITION p202011 VALUES LESS THAN('20201101'), PARTITION p202012 VALUES LESS THAN('20201201'), PARTITION p202013 VALUES LESS THAN(MAXVALUE) ); |
Insert data:
1 2 3 4 | INSERT INTO customer_address values('1','20200215'); INSERT INTO customer_address values('7','20200805'); INSERT INTO customer_address values('9','20201111'); INSERT INTO customer_address values('4','20201231'); |
Query a partition:
1 2 3 4 5 | SELECT * FROM customer_address PARTITION(p202009); ca_address_sk | ca_address_date ---------------+--------------------- 7 | 2020-08-05 00:00:00 (1 row) |
1 2 3 4 5 | CREATE table day_part(id int,d_time date) DISTRIBUTE BY HASH (id) PARTITION BY RANGE (d_time) (PARTITION p1 START('2022-01-01') END('2022-01-31') EVERY(interval '1 day')); ALTER TABLE day_part ADD PARTITION pmax VALUES LESS THAN (maxvalue); |
1 2 3 4 5 | CREATE table week_part(id int,w_time date) DISTRIBUTE BY HASH (id) PARTITION BY RANGE (w_time) (PARTITION p1 START('2021-01-01') END('2022-01-01') EVERY(interval '7 day')); ALTER TABLE week_part ADD PARTITION pmax VALUES LESS THAN (maxvalue); |
1 2 3 4 5 | CREATE table month_part(id int,m_time date) DISTRIBUTE BY HASH (id) PARTITION BY RANGE (m_time) (PARTITION p1 START('2021-01-01') END('2022-01-01') EVERY(interval '1 month')); ALTER TABLE month_part ADD PARTITION pmax VALUES LESS THAN (maxvalue); |