使用CREATE TABLE命令的PARTITION BY子句來創建一個分區表,這個分區表中的數據分配在一個或多個分區(和子分區)中。
語法介紹
CREATE TABLE命令語法有下面的三種形式:
列表分區語法
使用第一種形式創建一個列表分區表:
CREATE TABLE [ schema. ]table_name table_definition PARTITION BY LIST(column) [SUBPARTITION BY {RANGE|LIST|HASH} (column[, column ]...)] (list_partition_definition[, list_partition_definition]...);
其中list_partition_definition是:
PARTITION [partition_name] VALUES (value[, value]...) [TABLESPACE tablespace_name] [(subpartition, ...)]
范圍分區語法
使用第二種形式創建范圍分區表:
CREATE TABLE [ schema. ]table_name table_definition PARTITION BY RANGE(column[, column ]...) [SUBPARTITION BY {RANGE|LIST|HASH} (column[, column ]...)] (range_partition_definition[, range_partition_definition]...);
其中range partition definition是:
PARTITION [partition_name] VALUES LESS THAN (value[, value]...) [TABLESPACE tablespace_name] [(subpartition, ...)]
子分區語法
subpartition可能是下面兩種的其中一種
{list_subpartition | range_subpartition }
其中list_subpartition是:
SUBPARTITION [subpartition_name] VALUES (value[, value]...) [TABLESPACE tablespace_name]
其中range_subpartition是:
SUBPARTITION [subpartition_name] VALUES LESS THAN (value[, value]...) [TABLESPACE tablespace_name]
描述
CREATE TABLE... PARTITION BY命令用于創建帶有一個或多個分區的表,其中每個分區可能有一個或一個以上的子分區。對于定義的分區數量沒有上限, 但如果您要包括PARTITION BY子句,則必須至少指定一個分區規則。產生的表由創建這個表的用戶所有。
使用PARTITION BY LIST子句在指定列中輸入的值的基礎上對表進行分區。每個分區規則必須至少指定一個文本值,但對于您可能要指定的值的數量則沒有上限。包括一個用于指定DEFAULT匹配值的規則將任何不符合的記錄導入到指定的分區中。
使用PARTITION BY RANGE子句指定邊界規則來創建分區。每個分區規則必須至少包含一列有兩個運算符的數據類型(例如,一個大于等于運算符和一個小于運算符)。范圍邊界的評估是依據LESS THAN子句進行的,且范圍邊界是非包容性的。2013年1月1日這個日期邊界只會包括那些在2012年12月31日當天及之前的日期值。
范圍分區規則必須以升序方式指定。 如果INSERT命令存儲的記錄值超過了范圍分區表的最大限制將會失敗。除非分區規則中包括的邊界規則指定了MAXVALUE值。如果您沒有包括MAXVALUE分區規則,那么任何超過邊界規則指定的最大限制的記錄都會導致錯誤的產生。
使用關鍵字TABLESPACE指定分區或子分區要所屬的表空間名稱。如果您沒有指定表空間, 那么分區或子分區則會所屬于缺省表空間。
如果您使用CREATE TABLE語法在分區表上創建索引,那么這個索引也會同樣創建于每個分區或子分區中。
如果表定義包括SUBPARTITION BY子句, 那么這個表中的每個分區都會有至少一個子分區。每個子分區可能是明確定義的或是系統定義的。
如果子分區是系統定義的,那么服務器產生的子分區將所屬于缺省表空間中,且子分區的名稱將由服務器指定。服務器會創建下列內容:
如果SUBPARTITION BY子句指定了LIST, 那么服務器會創建一個DEFAULT子分區。
如果SUBPARTITION BY子句指定了RANGE,那么服務器會創建一個MAXVALUE子分區。
服務器所產生的子分區名稱是分區表名稱與一個唯一標識符的結合。您可以查詢表ALL_TAB_SUBPARTITIONS來檢查完整的子分區名稱列表。
參數
參數 | 參數說明 |
table name | 要創建的表名稱(可以采用模式限定的方式引用)。 |
table definition | 如在PostgreSQL核心文件中描述的那樣,給 |
partition name | 要創建的分區名稱。分區名稱在所有分區和子分區中必須是唯一的,且必須遵循給對象標識符命名的慣例。 |
subpartition name | 要創建的子分區名稱。子分區名稱在所有分區和子分區中必須是唯一的,且必須遵循給對象標識符命名的慣例。 |
column | 分區規則所基于的列名稱。 每條記錄都將存儲在一個符合于指定列值的分區中。 |
(value[, value]...) | 用 當給列表分區表指定規則時,要在最后的分區中包括關鍵字 當給范圍分區表指定規則時,在最后的分區規則中包括關鍵字 |
tablespace name | 分區或子分區所屬的表空間名稱。 |
PARTITION BY LIST示例
下列示例使用了PARTITION BY LIST子句創建了分區表(sales)。表sales在三個分區(europe、 asia 和 americas)中存儲信息:
CREATE TABLE sales
(
dept_no number,
part_no varchar2,
country varchar2(20),
date date,
amount number
)
PARTITION BY LIST(country)
(
PARTITION europe VALUES('FRANCE', 'ITALY'),
PARTITION asia VALUES('INDIA', 'PAKISTAN'),
PARTITION americas VALUES('US', 'CANADA')
);
在country列中指定的值對所產生的表進行了分區:
SELECT partition_name, high_value from ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+---------------------
americas | 'US', 'CANADA'
asia | 'INDIA', 'PAKISTAN'
europe | 'FRANCE', 'ITALY'
(3 rows)
Country列中帶有US或CANADA值的記錄存儲于americas分區中。
Country列中帶有INDIA 或 PAKISTAN值的記錄存儲于asia分區中。
Country列中帶有FRANCE 或 ITALY值的記錄存儲于europe分區中。
服務器會依據分區規則對下列語句進行評估,并將記錄存儲在europe分區中:
INSERT INTO sales VALUES (10, '9519a', 'FRANCE', '18-Aug-2012', '650000');
PARTITION BY RANGE示例
下列示例使用了PARTITION BY RANGE子句創建了分區表(sales)。表sales在四個分區(q1_2012、 q2_2012、 q3_2012 和 q4_2012)中存儲信息。
CREATE TABLE sales
(
dept_no number,
part_no varchar2,
country varchar2(20),
date date,
amount number
)
PARTITION BY RANGE(date)
(
PARTITION q1_2012
VALUES LESS THAN('2012-Apr-01'),
PARTITION q2_2012
VALUES LESS THAN('2012-Jul-01'),
PARTITION q3_2012
VALUES LESS THAN('2012-Oct-01'),
PARTITION q4_2012
VALUES LESS THAN('2013-Jan-01')
);
在date列中指定的值對產生的表進行了分區。
SELECT partition_name, high_value from ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+------------------------------------------------------------------
q1_2012 | FOR VALUES FROM (MINVALUE) TO ('01-APR-12 00:00:00')
q2_2012 | FOR VALUES FROM ('01-APR-12 00:00:00') TO ('01-JUL-12 00:00:00')
q3_2012 | FOR VALUES FROM ('01-JUL-12 00:00:00') TO ('01-OCT-12 00:00:00')
q4_2012 | FOR VALUES FROM ('01-OCT-12 00:00:00') TO ('01-JAN-13 00:00:00')
(4 rows)
在date列中任何帶有2012年4月1日之前的值的記錄都存儲于q1_2012分區中。
在date列中任何帶有2012年7月1日之前的值的記錄都存儲于分區q2_2012中。
在date列中任何帶有2012年10月1日之前的值的記錄都存儲于分區q3_2012中。
在date列中任何帶有2013年1月1日之前的值的記錄都存儲于分區q4_2012中。
服務器會依據分區規則對下列語句進行評估,并將記錄存儲在q3_2012分區中。
INSERT INTO sales VALUES (10, '9519a', 'FRANCE', '18-Aug-2012', '650000');
PARTITION BY RANGE、SUBPARTITION BY LIST示例
下列示例創建的分區表(sales)首先是通過事務日期進行分區。然后使用country列的值對范圍分區(q1_2012、 q2_2012、 q3_2012 和 q4_2012)進行了列表子分區的劃分。
CREATE TABLE sales
(
dept_no number,
part_no varchar2,
country varchar2(20),
date date,
amount number
)
PARTITION BY RANGE(date)
SUBPARTITION BY LIST(country)
(
PARTITION q1_2012
VALUES LESS THAN('2012-Apr-01')
(
SUBPARTITION q1_europe VALUES ('FRANCE', 'ITALY'),
SUBPARTITION q1_asia VALUES ('INDIA', 'PAKISTAN'),
SUBPARTITION q1_americas VALUES ('US', 'CANADA')
),
PARTITION q2_2012
VALUES LESS THAN('2012-Jul-01')
(
SUBPARTITION q2_europe VALUES ('FRANCE', 'ITALY'),
SUBPARTITION q2_asia VALUES ('INDIA', 'PAKISTAN'),
SUBPARTITION q2_americas VALUES ('US', 'CANADA')
),
PARTITION q3_2012
VALUES LESS THAN('2012-Oct-01')
(
SUBPARTITION q3_europe VALUES ('FRANCE', 'ITALY'),
SUBPARTITION q3_asia VALUES ('INDIA', 'PAKISTAN'),
SUBPARTITION q3_americas VALUES ('US', 'CANADA')
),
PARTITION q4_2012
VALUES LESS THAN('2013-Jan-01')
(
SUBPARTITION q4_europe VALUES ('FRANCE', 'ITALY'),
SUBPARTITION q4_asia VALUES ('INDIA', 'PAKISTAN'),
SUBPARTITION q4_americas VALUES ('US', 'CANADA')
)
);
這條語句創建的表有四個分區。每個分區都有三個子分區:
SELECT subpartition_name, high_value, partition_name FROM ALL_TAB_SUBPARTITIONS;
subpartition_name | high_value | partition_name
-------------------+-------------------------------------+----------------
q1_americas | FOR VALUES IN ('US', 'CANADA') | q1_2012
q1_asia | FOR VALUES IN ('INDIA', 'PAKISTAN') | q1_2012
q1_europe | FOR VALUES IN ('FRANCE', 'ITALY') | q1_2012
q2_americas | FOR VALUES IN ('US', 'CANADA') | q2_2012
q2_asia | FOR VALUES IN ('INDIA', 'PAKISTAN') | q2_2012
q2_europe | FOR VALUES IN ('FRANCE', 'ITALY') | q2_2012
q3_americas | FOR VALUES IN ('US', 'CANADA') | q3_2012
q3_asia | FOR VALUES IN ('INDIA', 'PAKISTAN') | q3_2012
q3_europe | FOR VALUES IN ('FRANCE', 'ITALY') | q3_2012
q4_americas | FOR VALUES IN ('US', 'CANADA') | q4_2012
q4_asia | FOR VALUES IN ('INDIA', 'PAKISTAN') | q4_2012
q4_europe | FOR VALUES IN ('FRANCE', 'ITALY') | q4_2012
(12 rows)
當把記錄添加到這個表中時,就會把date列中的值與在范圍分區規則中指定的值進行比較,服務器會選擇記錄應該所屬的分區。然后country列中的值就會與在列表子分區規則中指定的值相比較。當服務器定位了值的匹配信息時,記錄就會存儲在相應的子分區中。
任何添加到表中的記錄都會存儲在子分區中,因此所有的分區中都不會包含任何數據。
服務器會依據分區和子分區規則對下列語句進行評估,并將記錄存儲在q3_europe分區中:
INSERT INTO sales VALUES (10, '9519a', 'FRANCE', '18-Aug-2012', '650000');