全部產品
Search
文件中心

:在LIST或RANGE 分區表中處理偏離值

更新時間:Jul 06, 2024

本文介紹如何在LIST或RANGE 分區表中處理偏離值。

分區或子分區DEFAULT或MAXVALUE會捕獲任何不滿足定義給表的其他分區規則的記錄。

定義DEFAULT 分區

分區DEFAULT會捕獲那些在LIST分區(或子分區)表中不適用於任何其他分區的記錄。如果不包括一個DEFAULT規則,那麼任何不匹配分區約束中的其中一個值的記錄都會導致錯誤。每個LIST分區或子分區可能會有自己的DEFAULT規則。

DEFAULT規則的文法如下:
PARTITION partition_name VALUES (DEFAULT)

其中partition_name指定的是用於儲存那些不匹配其他分區規則的記錄的分區或子分區的名稱。

最後的一個樣本建立了列表分區表,在這個列表分區表中伺服器會決定要儲存基於列country值的資料的分區。如果您試圖添加一條記錄,且這條記錄中的列country值包含了一個沒在規則中列出的值,那麼PolarDB就會報錯:
acctg=# INSERT INTO sales VALUES
acctg-#   (40, '3000x', 'IRELAND', '01-Mar-2012', '45000');
ERROR:  inserted partition key does not map to any partition
下列樣本建立了相同的表,但添加了一個DEFAULT分區。 伺服器將儲存那些不匹配在分區規則中指定的值的記錄,其中這個分區規則是指定給分區others中的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'),
  PARTITION others VALUES (DEFAULT)
);
要測試分區DEFAULT,就要添加一條帶有列country值的記錄,且這個列country不與在分區約束中指定的任何一個國家匹配:
INSERT INTO sales VALUES
  (40, '3000x', 'IRELAND', '01-Mar-2012', '45000');
查詢表sales的內容確認了之前被拒絕的記錄現在是否儲存在分區sales_others中:
acctg=# SELECT tableoid::regclass, * FROM sales;
    tableoid    | dept_no | part_no | country  |        date        |  amount 
----------------+---------+---------+----------+--------------------+--------
 sales_others   |      40 | 3000x   | IRELAND  | 01-MAR-12 00:00:00 |   45000
(18 rows)
需要注意的是,PolarDB並沒有重新分配分區或子分區DEFAULT內容的方法。
  • 您不能使用ALTER TABLE…ADD PARTITION 命令把分區添加到帶有DEFAULT 規則的表中,但可以使用ALTER TABLE…SPLIT PARTITION 命令來劃分現有的分區。
  • 您不能使用ALTER TABLE…ADD SUBPARTITION命令把子分區添加到帶有DEFAULT 規則的表中,但可以使用ALTER TABLE…SPLIT SUBPARTITION命令來劃分現有的子分區。

定義 MAXVALUE 分區

分區或子分區MAXVALUE會捕獲那些不適用於在定界分割或子分區表中的任何其他分區的記錄。如果您不包括MAXVALUE規則,那麼任何超過分區規則所指定的最大限度的記錄都會導致錯誤的產生。每個分區或子分區也許都有自己的MAXVALUE分區。

需要注意的是, PolarDB並沒有重新分配分區或子分區MAXVALUE內容的方法:
  • 您不能使用ALTER TABLE ... ADD PARTITION語句把分區添加到帶有MAXVALUE規則的表中,但可以使用ALTER TABLE ... SPLIT PARTITION 語句來劃分現有的分區。
  • 您不能使用ALTER TABLE. ADD SUBPARTITION語句把子分區添加到帶有MAXVALUE規則的表中,但可以使用ALTER TABLE. SPLIT SUBPARTITION語句來劃分現有的子分區。
MAXVALUE 規則的文法如下:
PARTITION partition_name VALUES LESS THAN (MAXVALUE)

其中partition_name指定的是用於儲存那些不匹配其他分區規則的記錄的分區名稱。

最後的樣本建立了一個定界分割表,且這個定界分割表中的資料是基於列date的值進行分區的。如果您試圖添加一條date值超過了分區約束中列出的日期值的記錄,那麼PolarDB就會報錯:
acctg=# INSERT INTO sales VALUES
acctg-#   (40, '3000x', 'IRELAND', '01-Mar-2013', '45000');
ERROR:  inserted partition key does not map to any partition
下列CREATE TABLE命令建立了相同的表,但這個表中是MAXVALUE分區。這時並沒有產生錯誤,反而伺服器會儲存那些不匹配分區others中之前的分區約束的記錄。
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'),
  PARTITION others VALUES LESS THAN (MAXVALUE)
);
要測試分區MAXVALUE,就要添加一條帶有列date值的記錄,且這個列date 值還要超過在分區規則中列出的最後日期值。伺服器將在分區others中儲存這條記錄:
INSERT INTO sales VALUES
                    (40, '3000x', 'IRELAND', '2015-Oct-01', '45000');
查詢表sales的內容確認了之前被拒絕的記錄現在是否儲存在分區sales_others中:
acctg=# SELECT tableoid::regclass, * FROM sales;  
   tableoid    | dept_no | part_no | country  |        date        | amount 
---------------+---------+---------+----------+--------------------+---------
 sales_q1_2012 |      10 | 4519b   | FRANCE   | 17-JAN-12 00:00:00 |    45000
 sales_q1_2012 |      20 | 3788a   | INDIA    | 01-MAR-12 00:00:00 |    75000
 sales_q1_2012 |      30 | 9519b   | CANADA   | 01-FEB-12 00:00:00 |    75000
 sales_q2_2012 |      40 | 9519b   | US       | 12-APR-12 00:00:00 |   145000
 sales_q2_2012 |      20 | 3788a   | PAKISTAN | 04-JUN-12 00:00:00 |    37500
 sales_q2_2012 |      30 | 4519b   | CANADA   | 08-APR-12 00:00:00 |   120000
 sales_q2_2012 |      40 | 3788a   | US       | 12-MAY-12 00:00:00 |     4950
 sales_q3_2012 |      10 | 9519b   | ITALY    | 07-JUL-12 00:00:00 |    15000
 sales_q3_2012 |      10 | 9519a   | FRANCE   | 18-AUG-12 00:00:00 |   650000
 sales_q3_2012 |      10 | 9519b   | FRANCE   | 18-AUG-12 00:00:00 |   650000
 sales_q3_2012 |      20 | 3788b   | INDIA    | 21-SEP-12 00:00:00 |     5090
 sales_q3_2012 |      40 | 4788a   | US       | 23-SEP-12 00:00:00 |     4950
 sales_q4_2012 |      40 | 4577b   | US       | 11-NOV-12 00:00:00 |    25000
 sales_q4_2012 |      30 | 7588b   | CANADA   | 14-DEC-12 00:00:00 |    50000
 sales_q4_2012 |      40 | 4788b   | US       | 09-OCT-12 00:00:00 |    15000
 sales_q4_2012 |      20 | 4519a   | INDIA    | 18-OCT-12 00:00:00 |   650000
 sales_q4_2012 |      20 | 4519b   | INDIA    | 02-DEC-12 00:00:00 |     5090
 sales_others  |      40 | 3000x   | IRELAND  | 01-MAR-13 00:00:00 |    45000
(18 rows)