使用 ALTER TABLE… SPLIT SUBPARTITION 命令将单个二级分区划分为两个二级分区,并重新分配二级分区的内容。该命令具有两种变体。

第一种变体将一个范围二级分区拆分为两个二级分区:

ALTER TABLE table_name SPLIT SUBPARTITION subpartition_name
  AT (range_part_value)
  INTO
  (
    SUBPARTITION new_subpart1
      [TABLESPACE tablespace_name],
    SUBPARTITION new_subpart2
      [TABLESPACE tablespace_name]
  );

第二种变体将一个列表二级分区拆分为两个二级分区:

ALTER TABLE table_name SPLIT SUBPARTITION subpartition_name
  VALUES (value[, value]...)
  INTO
  (
    SUBPARTITION new_subpart1
      [TABLESPACE tablespace_name],
    SUBPARTITION new_subpart2
      [TABLESPACE tablespace_name]
  );

说明

ALTER TABLE...SPLIT SUBPARTITION 命令向现有二级分区表添加二级分区。定义的二级分区数没有上限。在您执行 ALTER TABLE...SPLIT SUBPARTITION 命令时,POLARDB for Oracle 创建两个新二级分区,将包含指定二级分区规则所约束的值的所有行移动到 new_subpart1 中,并将所有剩余行移动到 new_subpart2 中。

新二级分区规则必须引用定义现有二级分区的规则中指定的列。

包括 TABLESPACE 子句来指定新二级分区将位于的表空间。如果您没有指定表空间,将在默认表空间中创建二级分区。

如果为表编制了索引,将在新二级分区上创建索引。

要使用 ALTER TABLE... SPLIT SUBPARTITION 命令,您必须是表所有者,或具有超级用户(或管理)权限。

参数

参数 说明
table_name 分区表的名称(可能是 schema 限定的)。
subpartition_name 要拆分的二级分区的名称。
new_subpart1 要创建的第一个新二级分区的名称。二级分区名称必须在所有分区和二级分区中是唯一的,并且必须遵循对象标识符的命名约定。

new_subpart1 将获得满足 ALTER TABLE… SPLIT SUBPARTITION 命令中所指定的二级分区约束的行。

new_subpart2 要创建的第二个新二级分区的名称。二级分区名称必须在所有分区和二级分区中是唯一的,并且必须遵循对象标识符的命名约定。

new_subpart2 将获得按照以下命令中指定的二级分区约束未定向到 new_subpart1 的行:ALTER TABLE… SPLIT SUBPARTITION 命令。

(value[, value]...) 使用 value 指定将表条目分组到分区中所依据的用引号括起来的文本值(或文本值的逗号分隔列表)。每个分区规则都必须至少指定一个值,但对规则中指定的值的数量没有限制。value 还可能是 NULL、DEFAULT(如果指定 LIST 二级分区)或 MAXVALUE(如果指定 RANGE 二级分区)。
tablespace_name 分区或二级分区所在的表空间的名称。

示例 - 拆分列表二级分区

以下示例拆分列表二级分区,在两个新二级分区之间重新分配二级分区的内容。示例表 (sales) 是使用以下命令创建的:

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 first_half_2012 VALUES LESS THAN('01-JUL-2012')     (
      SUBPARTITION p1_europe VALUES ('ITALY', 'FRANCE'),
      SUBPARTITION p1_americas VALUES ('US', 'CANADA')
    ),
    PARTITION second_half_2012 VALUES LESS THAN('01-JAN-2013')     (
      SUBPARTITION p2_europe VALUES ('ITALY', 'FRANCE'),
      SUBPARTITION p2_americas VALUES ('US', 'CANADA')
    )   );

sales 表具有两个分区,分别名为 first_half_2012 和 second_half_2012。每个分区具有两个按范围定义的二级分区,它们根据 country 列的值将分区的内容分配到二级分区中:

acctg=# SELECT partition_name, subpartition_name, high_value FROM ALL_TAB_SUBPARTITIONS;
  partition_name  | subpartition_name |            high_value
------------------+-------------------+-----------------------------------
 FIRST_HALF_2012  | P1_AMERICAS       | FOR VALUES IN ('US', 'CANADA')
 FIRST_HALF_2012  | P1_EUROPE         | FOR VALUES IN ('ITALY', 'FRANCE')
 SECOND_HALF_2012 | P2_AMERICAS       | FOR VALUES IN ('US', 'CANADA')
 SECOND_HALF_2012 | P2_EUROPE         | FOR VALUES IN ('ITALY', 'FRANCE')
(4 rows)

以下命令向每个二级分区中添加行:

INSERT INTO sales VALUES
  (10, '4519b', 'FRANCE', '17-Jan-2012', '45000'),
  (40, '9519b', 'US', '12-Apr-2012', '145000'),
  (40, '4577b', 'US', '11-Nov-2012', '25000'),
  (30, '7588b', 'CANADA', '14-Dec-2012', '50000'),
  (30, '9519b', 'CANADA', '01-Feb-2012', '75000'),
  (30, '4519b', 'CANADA', '08-Apr-2012', '120000'),
  (40, '3788a', 'US', '12-May-2012', '4950'),
  (10, '9519b', 'ITALY', '07-Jul-2012', '15000'),
  (10, '9519a', 'FRANCE', '18-Aug-2012', '650000'),
  (10, '9519b', 'FRANCE', '18-Aug-2012', '650000'),
  (40, '4788a', 'US', '23-Sept-2012', '4950'),
  (40, '4788b', 'US', '09-Oct-2012', '15000');

SELECT 语句确认已在各二级分区中正确分配行:

acctg=# SELECT tableoid::regclass, * FROM sales;
     tableoid      | dept_no | part_no | country |        date        | amount
-------------------+---------+---------+---------+--------------------+--------
 sales_p1_americas |      40 | 9519b   | US      | 12-APR-12 00:00:00 | 145000
 sales_p1_americas |      30 | 9519b   | CANADA  | 01-FEB-12 00:00:00 |  75000
 sales_p1_americas |      30 | 4519b   | CANADA  | 08-APR-12 00:00:00 | 120000
 sales_p1_americas |      40 | 3788a   | US      | 12-MAY-12 00:00:00 |   4950
 sales_p1_europe   |      10 | 4519b   | FRANCE  | 17-JAN-12 00:00:00 |  45000
 sales_p2_americas |      40 | 4577b   | US      | 11-NOV-12 00:00:00 |  25000
 sales_p2_americas |      30 | 7588b   | CANADA  | 14-DEC-12 00:00:00 |  50000
 sales_p2_americas |      40 | 4788a   | US      | 23-SEP-12 00:00:00 |   4950
 sales_p2_americas |      40 | 4788b   | US      | 09-OCT-12 00:00:00 |  15000
 sales_p2_europe   |      10 | 9519b   | ITALY   | 07-JUL-12 00:00:00 |  15000
 sales_p2_europe   |      10 | 9519a   | FRANCE  | 18-AUG-12 00:00:00 | 650000
 sales_p2_europe   |      10 | 9519b   | FRANCE  | 18-AUG-12 00:00:00 | 650000
(12 rows)

以下命令将 p2_americas 二级分区拆分为两个新二级分区,并重新分配内容:

ALTER TABLE sales SPLIT SUBPARTITION p2_americas
  VALUES ('US')
  INTO
  (
    SUBPARTITION p2_us,
    SUBPARTITION p2_canada
  );

在调用命令之后,删除了 p2_americas 二级分区;在其位置上,服务器创建了两个新二级分区(p2_us 和 p2_canada):

acctg=# SELECT partition_name, subpartition_name, high_value FROM ALL_TAB_SUBPARTITIONS;
  partition_name  | subpartition_name |            high_value
------------------+-------------------+-----------------------------------
 FIRST_HALF_2012  | P1_AMERICAS       | FOR VALUES IN ('US', 'CANADA')
 FIRST_HALF_2012  | P1_EUROPE         | FOR VALUES IN ('ITALY', 'FRANCE')
 SECOND_HALF_2012 | P2_CANADA         | FOR VALUES IN ('CANADA')
 SECOND_HALF_2012 | P2_US             | FOR VALUES IN ('US')
 SECOND_HALF_2012 | P2_EUROPE         | FOR VALUES IN ('ITALY', 'FRANCE')
(5 rows)

查询 sales 表演示已重新分配 p2_americas 二级分区的内容:

acctg=# SELECT tableoid::regclass, * FROM sales;
     tableoid      | dept_no | part_no | country |        date        |amount
-------------------+---------+---------+---------+--------------------+------
 sales_p1_americas |      40 | 9519b   | US      | 12-APR-12 00:00:00 |145000
 sales_p1_americas |      30 | 9519b   | CANADA  | 01-FEB-12 00:00:00 | 75000
 sales_p1_americas |      30 | 4519b   | CANADA  | 08-APR-12 00:00:00 |120000
 sales_p1_americas |      40 | 3788a   | US      | 12-MAY-12 00:00:00 |  4950
 sales_p1_europe   |      10 | 4519b   | FRANCE  | 17-JAN-12 00:00:00 | 45000
 sales_p2_canada   |      30 | 7588b   | CANADA  | 14-DEC-12 00:00:00 | 50000
 sales_p2_europe   |      10 | 9519b   | ITALY   | 07-JUL-12 00:00:00 | 15000
 sales_p2_europe   |      10 | 9519a   | FRANCE  | 18-AUG-12 00:00:00 |650000
 sales_p2_europe   |      10 | 9519b   | FRANCE  | 18-AUG-12 00:00:00 |650000
 sales_p2_us       |      40 | 4577b   | US      | 11-NOV-12 00:00:00 | 25000
 sales_p2_us       |      40 | 4788a   | US      | 23-SEP-12 00:00:00 |  4950
 sales_p2_us       |      40 | 4788b   | US      | 09-OCT-12 00:00:00 | 15000
(12 rows)

示例 - 拆分范围二级分区

以下示例拆分范围二级分区,在两个新二级分区之间重新分配二级分区的内容。示例表 (sales) 是使用以下命令创建的:

CREATE TABLE sales
(
  dept_no     number,
  part_no     varchar2,
  country     varchar2(20),
  date        date,
  amount      number
)
PARTITION BY LIST(country)
  SUBPARTITION BY RANGE(date)
(
  PARTITION europe VALUES('FRANCE', 'ITALY')
    (
      SUBPARTITION europe_2011          VALUES LESS THAN('2012-Jan-01'),
      SUBPARTITION europe_2012          VALUES LESS THAN('2013-Jan-01')
    ),
  PARTITION asia VALUES('INDIA', 'PAKISTAN')
    (
      SUBPARTITION asia_2011          VALUES LESS THAN('2012-Jan-01'),
      SUBPARTITION asia_2012          VALUES LESS THAN('2013-Jan-01')
    ),
  PARTITION americas VALUES('US', 'CANADA')
    (
      SUBPARTITION americas_2011          VALUES LESS THAN('2012-Jan-01'),
      SUBPARTITION americas_2012          VALUES LESS THAN('2013-Jan-01')
    )
);

sales 表具有三个分区(europe、asia 和 americas)。每个分区具有两个按范围定义的二级分区,它们按 date 列的值将分区的内容分类到二级分区中:

acctg=# SELECT partition_name, subpartition_name, high_value FROM ALL_TAB_SUBPARTITIONS;
 partition_name | subpartition_name |                   high_value
----------------+-------------------+------------------------------------------------
 EUROPE         | EUROPE_2012       | FOR VALUES FROM ('01-JAN-12 00:00:00') TO ('01-JAN-13 00:00:00')
 EUROPE         | EUROPE_2011       | FOR VALUES FROM (MINVALUE) TO ('01-JAN-12 00:00:00')
 ASIA           | ASIA_2012         | FOR VALUES FROM ('01-JAN-12 00:00:00') TO ('01-JAN-13 00:00:00')
 ASIA           | ASIA_2011         | FOR VALUES FROM (MINVALUE) TO ('01-JAN-12 00:00:00')
 AMERICAS       | AMERICAS_2012     | FOR VALUES FROM ('01-JAN-12 00:00:00') TO ('01-JAN-13 00:00:00')
 AMERICAS       | AMERICAS_2011     | FOR VALUES FROM (MINVALUE) TO ('01-JAN-12 00:00:00')
(6 rows)

以下命令向每个二级分区中添加行:

INSERT INTO sales VALUES
  (10, '4519b', 'FRANCE', '17-Jan-2012', '45000'),
  (20, '3788a', 'INDIA', '01-Mar-2012', '75000'),
  (40, '9519b', 'US', '12-Apr-2012', '145000'),
  (20, '3788a', 'PAKISTAN', '04-Jun-2012', '37500'),
  (40, '4577b', 'US', '11-Nov-2012', '25000'),
  (30, '7588b', 'CANADA', '14-Dec-2012', '50000'),
  (30, '9519b', 'CANADA', '01-Feb-2012', '75000'),
  (30, '4519b', 'CANADA', '08-Apr-2012', '120000'),
  (40, '3788a', 'US', '12-May-2012', '4950'),
  (10, '9519b', 'ITALY', '07-Jul-2012', '15000'),
  (10, '9519a', 'FRANCE', '18-Aug-2012', '650000'),
  (10, '9519b', 'FRANCE', '18-Aug-2012', '650000'),
  (20, '3788b', 'INDIA', '21-Sept-2012', '5090'),
  (40, '4788a', 'US', '23-Sept-2012', '4950'),
  (40, '4788b', 'US', '09-Oct-2012', '15000'),
  (20, '4519a', 'INDIA', '18-Oct-2012', '650000'),
  (20, '4519b', 'INDIA', '2-Dec-2012', '5090');

SELECT 语句确认已在各二级分区中分配行:

acctg=# SELECT tableoid::regclass, * FROM sales;
      tableoid       | dept_no | part_no | country  |        date        | amount
---------------------+---------+---------+----------+--------------------+--------
 sales_americas_2012 |      40 | 9519b   | US       | 12-APR-12 00:00:00 | 145000
 sales_americas_2012 |      40 | 4577b   | US       | 11-NOV-12 00:00:00 |  25000
 sales_americas_2012 |      30 | 7588b   | CANADA   | 14-DEC-12 00:00:00 |  50000
 sales_americas_2012 |      30 | 9519b   | CANADA   | 01-FEB-12 00:00:00 |  75000
 sales_americas_2012 |      30 | 4519b   | CANADA   | 08-APR-12 00:00:00 | 120000
 sales_americas_2012 |      40 | 3788a   | US       | 12-MAY-12 00:00:00 |   4950
 sales_americas_2012 |      40 | 4788a   | US       | 23-SEP-12 00:00:00 |   4950
 sales_americas_2012 |      40 | 4788b   | US       | 09-OCT-12 00:00:00 |  15000
 sales_europe_2012   |      10 | 4519b   | FRANCE   | 17-JAN-12 00:00:00 |  45000
 sales_europe_2012   |      10 | 9519b   | ITALY    | 07-JUL-12 00:00:00 |  15000
 sales_europe_2012   |      10 | 9519a   | FRANCE   | 18-AUG-12 00:00:00 | 650000
 sales_europe_2012   |      10 | 9519b   | FRANCE   | 18-AUG-12 00:00:00 | 650000
 sales_asia_2012     |      20 | 3788a   | INDIA    | 01-MAR-12 00:00:00 |  75000
 sales_asia_2012     |      20 | 3788a   | PAKISTAN | 04-JUN-12 00:00:00 |  37500
 sales_asia_2012     |      20 | 3788b   | INDIA    | 21-SEP-12 00:00:00 |   5090
 sales_asia_2012     |      20 | 4519a   | INDIA    | 18-OCT-12 00:00:00 | 650000
 sales_asia_2012     |      20 | 4519b   | INDIA    | 02-DEC-12 00:00:00 |   5090
(17 rows)

以下命令将 americas_2012 二级分区拆分为两个新二级分区,并重新分配内容:

ALTER TABLE sales    SPLIT SUBPARTITION americas_2012    AT('2012-Jun-01')
  INTO
  (     SUBPARTITION americas_p1_2012,
    SUBPARTITION americas_p2_2012
  );

在调用命令之后,删除了 americas_2012 二级分区;在其位置上,服务器创建了两个新二级分区(americas_p1_2012 和 americas_p2_2012):

acctg=# SELECT partition_name, subpartition_name, high_value FROM ALL_TAB_SUBPARTITIONS;
 partition_name | subpartition_name |                 high_value
----------------+-------------------+--------------------------------------------------
 EUROPE         | EUROPE_2011       | FOR VALUES FROM (MINVALUE) TO ('01-JAN-12 00:00:00')
 EUROPE         | EUROPE_2012       | FOR VALUES FROM ('01-JAN-12 00:00:00') TO ('01-JAN-13 00:00:00')
 ASIA           | ASIA_2011         | FOR VALUES FROM (MINVALUE) TO ('01-JAN-12 00:00:00')
 ASIA           | ASIA_2012         | FOR VALUES FROM ('01-JAN-12 00:00:00') TO ('01-JAN-13 00:00:00')
 AMERICAS       | AMERICAS_2011     | FOR VALUES FROM (MINVALUE) TO ('01-JAN-12 00:00:00')
 AMERICAS       | AMERICAS_P1_2012  | FOR VALUES FROM ('01-JAN-12 00:00:00') TO ('01-JUN-12 00:00:00')
 AMERICAS       | AMERICAS_P2_2012  | FOR VALUES FROM ('01-JUN-12 00:00:00') TO ('01-JAN-13 00:00:00')
(7 rows)

查询 sales 表演示已重新分配二级分区的内容:

acctg=# SELECT tableoid::regclass, * FROM sales;
        tableoid        | dept_no | part_no | country  |        date        | amount
------------------------+---------+---------+----------+--------------------+--------
 sales_americas_p1_2012 |      40 | 9519b   | US       | 12-APR-12 00:00:00 | 145000
 sales_americas_p1_2012 |      30 | 9519b   | CANADA   | 01-FEB-12 00:00:00 |  75000
 sales_americas_p1_2012 |      30 | 4519b   | CANADA   | 08-APR-12 00:00:00 | 120000
 sales_americas_p1_2012 |      40 | 3788a   | US       | 12-MAY-12 00:00:00 |   4950
 sales_americas_p2_2012 |      40 | 4577b   | US       | 11-NOV-12 00:00:00 |  25000
 sales_americas_p2_2012 |      30 | 7588b   | CANADA   | 14-DEC-12 00:00:00 |  50000
 sales_americas_p2_2012 |      40 | 4788a   | US       | 23-SEP-12 00:00:00 |   4950
 sales_americas_p2_2012 |      40 | 4788b   | US       | 09-OCT-12 00:00:00 |  15000
 sales_europe_2012      |      10 | 4519b   | FRANCE   | 17-JAN-12 00:00:00 |  45000
 sales_europe_2012      |      10 | 9519b   | ITALY    | 07-JUL-12 00:00:00 |  15000
 sales_europe_2012      |      10 | 9519a   | FRANCE   | 18-AUG-12 00:00:00 | 650000
 sales_europe_2012      |      10 | 9519b   | FRANCE   | 18-AUG-12 00:00:00 | 650000
 sales_asia_2012        |      20 | 3788a   | INDIA    | 01-MAR-12 00:00:00 |  75000
 sales_asia_2012        |      20 | 3788a   | PAKISTAN | 04-JUN-12 00:00:00 |  37500
 sales_asia_2012        |      20 | 3788b   | INDIA    | 21-SEP-12 00:00:00 |   5090
 sales_asia_2012        |      20 | 4519a   | INDIA    | 18-OCT-12 00:00:00 | 650000
 sales_asia_2012        |      20 | 4519b   | INDIA    | 02-DEC-12 00:00:00 |   5090
(17 rows)