Interval范圍分區(qū)
PolarDB PostgreSQL版(兼容Oracle)支持Interval(間隔)范圍分區(qū)功能,本文詳細(xì)介紹了其語(yǔ)法和示例。
簡(jiǎn)介
PolarDB PostgreSQL版(兼容Oracle)提供了自動(dòng)創(chuàng)建范圍分區(qū)的特性,即Interval范圍分區(qū),在您創(chuàng)建范圍分區(qū)表時(shí),可以指定Interval表達(dá)式,確定自動(dòng)分區(qū)的范圍。當(dāng)插入的值無(wú)法匹配到已有分區(qū)時(shí),PolarDB PostgreSQL版(兼容Oracle)將自動(dòng)為您創(chuàng)建一個(gè)分區(qū)。
Interval范圍分區(qū)是范圍分區(qū)的擴(kuò)展,它允許數(shù)據(jù)庫(kù)在新插入的數(shù)據(jù)超出現(xiàn)有分區(qū)的范圍時(shí)自動(dòng)創(chuàng)建新分區(qū)。要實(shí)現(xiàn)間隔范圍分區(qū),請(qǐng)包含INTERVAL子句并指定新分區(qū)的范圍大小。范圍分區(qū)的高值(也稱為轉(zhuǎn)換點(diǎn))由范圍分區(qū)鍵值確定。數(shù)據(jù)庫(kù)會(huì)為插入的數(shù)據(jù)創(chuàng)建新的分區(qū),其值超出了該高值。
如果間隔設(shè)置為1個(gè)月,并且在當(dāng)前插入最新分區(qū)之后兩個(gè)月的數(shù)據(jù),則僅創(chuàng)建該月的分區(qū),而不創(chuàng)建中間分區(qū)。 例如,您可以創(chuàng)建一個(gè)間隔范圍分區(qū)表,間隔為每月,最新分區(qū)的范圍為2019年1月15日至2019年2月15日。如果您嘗試插入2019年5月10日的數(shù)據(jù),則所需的分區(qū)為4月15日到5月15日被創(chuàng)建,數(shù)據(jù)將插入到該分區(qū)中,跳過(guò)2019年2月15日至2019年3月15日和2019年3月15日至2019年4月15日的分區(qū),且不會(huì)創(chuàng)建這兩個(gè)分區(qū)。
使用限制
以下限制適用于INTERVAL子句:
區(qū)間范圍分區(qū)僅限于單個(gè)分區(qū)鍵,該鍵必須是數(shù)字或日期范圍。
必須至少定義一個(gè)范圍分區(qū)。
在復(fù)合分區(qū)中,間隔范圍分區(qū)可用于主分區(qū)機(jī)制,但不支持子分區(qū)級(jí)別。
不支持索引組織表。
不能在LIST分區(qū)表上創(chuàng)建域索引。
DEFAULT和MAXVALUE不能為區(qū)間范圍分區(qū)表定義。
不能在分區(qū)鍵列中指定NULL、Not-a-Number或Infinity值。
區(qū)間范圍分區(qū)表達(dá)式必須產(chǎn)生常量值并且不能為負(fù)值。
間隔范圍分區(qū)表的分區(qū)僅支持按照升序創(chuàng)建。
語(yǔ)法
CREATE TABLE [ schema. ]<table_name>
<table_definition>
PARTITION BY RANGE(<column>[, <column> ]...)
[INTERVAL (<constant> | <expression>)]
[SUBPARTITION BY {RANGE|LIST|HASH} (<column>[, <column> ]...)]
(<range_partition_definition>[, <range_partition_definition>]...)
[ENABLE ROW MOVEMENT];
WHERE range_partition_definition IS:
PARTITION [<partition_name>]
VALUES LESS THAN (<value>[, <value>]...)
[TABLESPACE <tablespace_name>]
[(<subpartition>, ...)]
INTERVAL
參數(shù)僅支持設(shè)置數(shù)字和時(shí)間間隔:
數(shù)字
相近的10個(gè)數(shù)字進(jìn)入同一個(gè)分區(qū),示例如下:
INTERVAL (10)
時(shí)間間隔
按年設(shè)置自動(dòng)分區(qū),示例如下:
INTERVAL (NUMTOYMINTERVAL(1,'year'))
按月設(shè)置自動(dòng)分區(qū),示例如下:
INTERVAL (NUMTOYMINTERVAL(1,'month'))
按日設(shè)置自動(dòng)分區(qū),示例如下:
INTERVAL (NUMTODSINTERVAL(1,'day'))
按周設(shè)置自動(dòng)分區(qū),示例如下:
INTERVAL (NUMTODSINTERVAL(7,'day'))
關(guān)于其他參數(shù)的介紹,請(qǐng)參見(jiàn)CREATE TABLE...PARTITION BY。
示例
本示例展示了按sold_month
列上的時(shí)間間隔分區(qū)的sales
表。創(chuàng)建范圍分區(qū)是為了建立一個(gè)轉(zhuǎn)換點(diǎn),在轉(zhuǎn)換點(diǎn)之外創(chuàng)建新的分區(qū)。
在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)新的Interval范圍分區(qū),并將數(shù)據(jù)添加到一個(gè)表中。
CREATE TABLE sales
(
prod_id int,
prod_quantity int,
sold_month date
)
PARTITION BY RANGE(sold_month)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(
PARTITION p1
VALUES LESS THAN('15-JAN-2019'),
PARTITION p2
VALUES LESS THAN('15-FEB-2019')
);
------查詢ALL_TAB_PARTITIONS視圖
SELECT partition_name, high_value from ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+----------------------
P1 | '15-JAN-19 00:00:00'
P2 | '15-FEB-19 00:00:00'
(2 rows)
-----向超過(guò)范圍分區(qū)的高值的sales表中插入數(shù)據(jù)
INSERT INTO sales VALUES (1,200,'10-MAY-2019');
INSERT 0 1
------成功插入數(shù)據(jù),系統(tǒng)將生成一個(gè)Interval范圍分區(qū)名稱,該名稱因每個(gè)會(huì)話而不同
SELECT partition_name, high_value FROM ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+----------------------
P1 | '15-JAN-19 00:00:00'
P2 | '15-FEB-19 00:00:00'
SYS916340103 | '15-MAY-19 00:00:00'
(3 rows)
范圍分區(qū)和Interval范圍分區(qū)互轉(zhuǎn)示例
范圍分區(qū)轉(zhuǎn)換為Interval范圍分區(qū)
ALTER TABLE...SET INTERVAL命令可將現(xiàn)有的范圍分區(qū)表轉(zhuǎn)換為Interval范圍分區(qū)表。
設(shè)置范圍或時(shí)間間隔后,數(shù)據(jù)庫(kù)會(huì)自動(dòng)創(chuàng)建一個(gè)指定范圍或時(shí)間間隔的新分區(qū),并將數(shù)據(jù)插入到新分區(qū)中。
語(yǔ)法如下:
ALTER TABLE <table_name> SET INTERVAL (<constant> | <expression>);
Interval范圍分區(qū)轉(zhuǎn)換為范圍分區(qū)
SET INTERVAL()命令用于禁用Interval范圍分區(qū)。禁用后,數(shù)據(jù)庫(kù)會(huì)將Interval范圍分區(qū)表轉(zhuǎn)換為范圍分區(qū)表,并將Interval范圍分區(qū)的范圍或時(shí)間間隔設(shè)置為范圍分區(qū)的范圍或時(shí)間間隔。
語(yǔ)法如下:
ALTER TABLE <table_name> SET INTERVAL ();
示例
以下示例會(huì)將表sales從范圍分區(qū)轉(zhuǎn)換為Interval范圍分區(qū),并在分區(qū)表中插入數(shù)據(jù)。
------創(chuàng)建范圍分區(qū)表sales
CREATE TABLE sales
(
prod_id int,
prod_quantity int,
sold_month date
)
PARTITION BY RANGE(sold_month)
(
PARTITION p1
VALUES LESS THAN('15-JAN-2019'),
PARTITION p2
VALUES LESS THAN('15-FEB-2019')
);
------查詢ALL_TAB_PARTITIONS視圖
SELECT partition_name, high_value FROM ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+----------------------
P1 | FOR VALUES FROM ('15-JAN-19 00:00:00') TO ('15-FEB-19 00:00:00')
P2 | FOR VALUES FROM (MINVALUE) TO ('15-JAN-19 00:00:00')
(2 rows)
------將范圍分區(qū)表轉(zhuǎn)換為Interval范圍分區(qū)表
ALTER TABLE sales SET INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'));
-----插入超過(guò)范圍分區(qū)的數(shù)據(jù)
INSERT INTO sales VALUES (1,100,'05-APR-2019');
INSERT 0 1
SELECT partition_name, high_value FROM ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+----------------------
SYS596430103 | FOR VALUES FROM ('15-MAR-19 00:00:00') TO ('15-APR-19 00:00:00')
P1 | FOR VALUES FROM ('15-JAN-19 00:00:00') TO ('15-FEB-19 00:00:00')
P2 | FOR VALUES FROM (MINVALUE) TO ('15-JAN-19 00:00:00')
(3 rows)