10、添加一个分区
你可以通过下面的语句添加一个分区。
ALTER TABLE sales ADD PARTITION START (date '2009-02-01') INCLUSIVE END (date '2009-03-01') EXCLUSIVE;
如果你在创建表的时候没有使用subpartition template,你需要在添加分区的时候给出子分区定义,例如:
ALTER TABLE sales ADD PARTITION START (date '2009-02-01') INCLUSIVE END (date '2009-03-01') EXCLUSIVE ( SUBPARTITION usa VALUES ('usa'), SUBPARTITION asia VALUES ('asia'), SUBPARTITION europe VALUES ('europe') );
你也可以单独修改一个二级分区:
CREATE TABLE sales_two_level (trans_id int, date date, amount decimal(9,2), region text) PARTITION BY RANGE (date) SUBPARTITION BY LIST (region) SUBPARTITION TEMPLATE ( SUBPARTITION usa VALUES ('usa'), SUBPARTITION asia VALUES ('asia'), SUBPARTITION europe VALUES ('europe')) (START (date '2011-01-01') INCLUSIVE END (date '2012-01-01') EXCLUSIVE EVERY (INTERVAL '1 month'), DEFAULT PARTITION outlying_dates); ALTER TABLE sales_two_level ALTER PARTITION FOR (RANK(12)) ADD PARTITION africa VALUES ('africa');
其中RANK(12)表示第12个分区。
注:指定一个分区可以使用
PARTITION FOR (value) or PARTITION FOR(RANK(number))语法。
如果你的分区表有一个Default分区的话,你不可以向该分区表添加分区,你只可以通过分裂Default分区的方法来添加分区。
11、重命名分区
Partitioned tables use the following naming convention. Partitioned subtable names are subject to uniqueness requirements and length limitations.
分区表使用以下的命名规则。
<parentname>_<level>_prt_<partition_name>
例如:sales_1_prt_jan08指的是父表名字为sales,第一级分区名字为jan08的分区。在创建Range分区表时, 如果没有指定分区名字,分区的名字会自动生成为数字。
改变父表的名字同时会改变分区表的名字。例如:
postgres=# ALTER TABLE sales_two_level RENAME TO globalsales; postgres=# \d+ globalsales Append-Only Table "public.globalsales" Column | Type | Modifiers | Storage | Description ----------+--------------+-----------+----------+------------- trans_id | integer | | plain | date | date | | plain | amount | numeric(9,2) | | main | region | text | | extended | Compression Type: None Compression Level: 0 Block Size: 32768 Checksum: f Child tables: globalsales_1_prt_10, globalsales_1_prt_11, globalsales_1_prt_12, globalsales_1_prt_13, globalsales_1_prt_2, globalsales_1_prt_3, globalsales_1_prt_4, globalsales_1_prt_5, globalsales_1_prt_6, globalsales_1_prt_7, globalsales_1_prt_8, globalsales_1_prt_9, globalsales_1_prt_outlying_dates Has OIDs: no Options: appendonly=true Distributed randomly Partition by: (date)
你可以改变一个分区的名字,例如:
ALTER TABLE sales RENAME PARTITION FOR ('2008-01-01') TO jan08;
12、添加一个默认分区 (Default Partition)
你可以使用Alter命令添加一个默认分区。不满足任何分区条件的分区会进入默认分区。
ALTER TABLE sales ADD DEFAULT PARTITION other; ALTER TABLE sales ALTER PARTITION FOR (RANK(1)) ADD DEFAULT PARTITION other;
13、删除一个分区
你可以通过Alter命令删除一个分区。如果一个分区有子分区,在删除该分区的时候,它的子分区也会被删除。
对于一个分区的事实表,删除分区常用来删除保留时间窗口外的分区数据。
ALTER TABLE sales DROP PARTITION FOR (RANK(1));
14、Truncate分区
你可以通过Alter命令Truncate一个分区。在Truncate一个分区时,其子分区也会被Truncate。
ALTER TABLE sales TRUNCATE PARTITION FOR (RANK(1));
15、交换分区
你可以使用Alter Table命令来交换一个分区。交换分区操作把一个表和一个已存在分区进行交换(Swap)。你只可以交换叶子节点分区。
分区交换通常对数据加载很有用。例如,你可以首先加载数据到一个中间表,然后把该中间表交换到分区表内部。
你也可以利用分区交换改变分区表的类型。例如:
CREATE TABLE sales (id int, date date, amt decimal(10,2)) PARTITION BY RANGE (date) ( START (date '2008-01-01') INCLUSIVE END (date '2009-01-01') EXCLUSIVE EVERY (INTERVAL '1 month') ); CREATE TABLE jan (LIKE sales) WITH (appendonly=true, orientation=parquet, compresstype = snappy); INSERT INTO jan SELECT * FROM sales_1_prt_1 ; ALTER TABLE sales EXCHANGE PARTITION FOR (RANK(1)) WITH TABLE jan;
16、分区分裂
你可以使用Alter分裂一个已经存在的分区,例如下面的例子把sales_split分区表分裂成两个子分区:jan081to15和 jan0816to31。
CREATE TABLE sales_split (id int, date date, amt decimal(10,2)) PARTITION BY RANGE (date) ( START (date '2008-01-01') INCLUSIVE END (date '2009-01-01') EXCLUSIVE EVERY (INTERVAL '1 month') ); ALTER TABLE sales_split SPLIT PARTITION FOR ('2008-01-01') AT ('2008-01-16') INTO (PARTITION jan081to15, PARTITION jan0816to31);
如果你的分区表有Default分区的话,你只可以通过分裂Default分区的方法来添加子分区。例如,下面的例子通过分裂 Default分区的方式添加一个jan2009分区。
CREATE TABLE sales_split_default (id int, date date, amt decimal(10,2)) PARTITION BY RANGE (date) ( START (date '2008-01-01') INCLUSIVE END (date '2009-01-01') EXCLUSIVE EVERY (INTERVAL '1 month'), DEFAULT PARTITION extra); ALTER TABLE sales_split_default SPLIT DEFAULT PARTITION START ('2009-01-01') INCLUSIVE END ('2009-02-01') EXCLUSIVE INTO (PARTITION jan2009, default partition);
17、修改子分区模版
你可以通过Alter命令修改子分区模版。先创建一个两级分区表。
CREATE TABLE sales (trans_id int, date date, amount decimal(9,2), region text) DISTRIBUTED BY (trans_id) PARTITION BY RANGE (date) SUBPARTITION BY LIST (region) SUBPARTITION TEMPLATE ( SUBPARTITION usa VALUES ('usa'), SUBPARTITION asia VALUES ('asia'), SUBPARTITION europe VALUES ('europe'), DEFAULT SUBPARTITION other_regions ) ( START (date '2014-01-01') INCLUSIVE END (date '2014-04-01') EXCLUSIVE EVERY (INTERVAL '1 month') );
下面这条命令修改子分区模版。
ALTER TABLE sales SET SUBPARTITION TEMPLATE ( SUBPARTITION usa VALUES ('usa'), SUBPARTITION asia VALUES ('asia'), SUBPARTITION europe VALUES ('europe'), SUBPARTITION africa VALUES ('africa'), DEFAULT SUBPARTITION regions );
下面这条命令可以删除子分区模版。
ALTER TABLE sales SET SUBPARTITION TEMPLATE ();
对已存在非分区表进行分区
对已存在表进行分区,你需要创建一个新的分区表,并把需要分区的表的数据导入新的表。并把相关权限分配好。
CREATE TABLE sales2 (LIKE sales) PARTITION BY RANGE (date) ( START (date '2008-01-01') INCLUSIVE END (date '2009-01-01') EXCLUSIVE EVERY (INTERVAL '1 month') ); INSERT INTO sales2 SELECT * FROM sales; DROP TABLE sales; ALTER TABLE sales2 RENAME TO sales; GRANT ALL PRIVILEGES ON sales TO admin; GRANT SELECT ON sales TO guest;