使用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核心檔案中描述的那樣,給create table 語句的列名稱、資料類型及約束資訊。 |
partition name | 要建立的分區名稱。分區名稱在所有分區和子分區中必須是唯一的,且必須遵循給物件識別碼命名的慣例。 |
subpartition name | 要建立的子分區名稱。子分區名稱在所有分區和子分區中必須是唯一的,且必須遵循給物件識別碼命名的慣例。 |
column | 分區規則所基於的列名稱。 每條記錄都將儲存在一個符合於指定列值的分區中。 |
(value[, value]...) | 用 當給列表分區表指定規則時,要在最後的分區中包括關鍵字 當給定界分割表指定規則時,在最後的分區規則中包括關鍵字 |
tablespace name | 分區或子分區所屬的資料表空間名稱。 |
PARTITION BY LIST樣本
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')
);
acctg=# 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分區中。
INSERT INTO sales VALUES (10, '9519a', 'FRANCE', '18-Aug-2012', '650000');
PARTITION BY RANGE樣本
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')
);
acctg=# SELECT partition_name, high_value from ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+---------------
q4_2012 | '2013-Jan-01'
q3_2012 | '2012-Oct-01'
q2_2012 | '2012-Jul-01'
q1_2012 | '2012-Apr-01'
(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中。
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')
)
);
acctg=# SELECT subpartition_name, high_value, partition_name FROM ALL_TAB_SUBPARTITIONS;
subpartition_name | high_value | partition_name + +
q4_asia | 'INDIA', 'PAKISTAN' | q4_2012
q4_europe | 'FRANCE', 'ITALY' | q4_2012
SUBPARTITION q4_ SUBPARTITION q4_ SUBPARTITION q4_
q4_americas | 'US', 'CANADA' | q4_2012
q3_americas | 'US', 'CANADA' | q3_2012
q3_asia | 'INDIA', | q3_2012
q3_europe | 'PAKISTAN' | q3_2012
q2_americas | 'FRANCE', 'ITALY' | q2_2012
q2_asia | 'US', 'CANADA' | q2_2012
q2_europe | 'INDIA','PAKISTAN' | q2_2012
q1_americas | 'FRANCE', 'ITALY' | q1_2012
q1_asia | 'US', 'CANADA' | q1_2012
q1_europe | 'INDIA', 'PAKISTAN' | q1_2012
12 rows)
當把記錄添加到這個表中時,就會把date列中的值與在定界分割規則中指定的值進行比較,伺服器會選擇記錄應該所屬的分區。然後country列中的值就會與在列表子分區規則中指定的值相比較。當伺服器定位了值的匹配資訊時,記錄就會儲存在相應的子分區中。
任何添加到表中的記錄都會儲存在子分區中,因此所有的分區中都不會包含任何資料。
INSERT INTO sales VALUES (10, '9519a', 'FRANCE', '18-Aug-2012', '650000');