本文介绍了修改表的分区的语法,包括分区的分裂、合并和迁移等。本语法仅适用于AUTO模式数据库。

分区分裂

将表的一个分区分裂成一个或多个分区。

Range/Range column分区表分裂
  • 语法
    ALTER TABLE identifier SPLIT PARTITION identifier INTO
     (partition_definition,partition_definition, [, partition_definition] ...);
    
     partition_definition:
        PARTITION partition_name
            [VALUES
                {LESS THAN {(value_list) | MAXVALUE}]
  • 示例

    执行以下SQL,创建表tb1:

    CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
     (PARTITION p1 VALUES LESS THAN(20),
      PARTITION p2 VALUES LESS THAN(100))

    执行以下SQL,将p1分裂成p10,p11,p12:

    ALTER TABLE tb1 SPLIT PARTITION p1 INTO
    (PARTITION p10 VALUES LESS THAN (8),
    PARTITION p11 VALUES LESS THAN(15),
    PARTITION p12 VALUES LESS THAN(20))

对于Range分区表,PolarDB-X还支持将一个Range在其范围内按任意点一分为二。

  • 语法
    ALTER TABLE identifier SPLIT PARTITION identifier AT(number) INTO
     (PARTITION identifier,
      PARTITION identifier);
  • 示例

    对于tb1表,支持将分区p1分裂:

    ALTER TABLE tb1 SPLIT PARTITION p1 AT(9) INTO (partition p11, partition p12)

    该SQL等价于下面这条语句:

    ALTER TABLE tb1 SPLIT PARTITION p1 INTO
    (PARTITION p11 VALUES LESS THAN(9),
    PARTITION p12 VALUES LESS THAN(20));
List/List column分区表分裂
  • 语法
    ALTER TABLE identifier SPLIT PARTITION identifier INTO
     (partition_definition,partition_definition, [, partition_definition] ...);
    
     partition_definition:
        PARTITION partition_name
            [VALUES IN (value_list | default)}]
  • 示例

    执行以下SQL,创建表tb1:

    CREATE TABLE tb1(a int) PARTITION BY LIST(a)
     (PARTITION p1 VALUES IN(1, 2, 3, 4, 5, 6),
      PARTITION p2 VALUES IN(7,8,9),
      PARTITION p3 VALUES IN(default))

    执行以下SQL,将p1分裂成p10,p11,p12。

    ALTER TABLE tb1 SPLIT PARTITION p1 INTO
    (PARTITION p10 VALUES IN (1,3,5),
    PARTITION p11 VALUES IN (2,4),
    PARTITION p12 VALUES IN (6))

    由于分区p3是default分区,表示1~9之外的分区键对应的值全部在p3分区。对于default分区,PolarDB-X也支持将部分value从default分区中分裂出来。执行以下SQL,将10~15从p3中分裂出来:

    ALTER TABLE tb1 SPLIT PARTITION p3 INTO
    (PARTITION p30 VALUES IN (10,11,12),
    PARTITION p31 VALUES IN (13,14,15),
    PARTITION p32 VALUES IN (default))
Hash/key分区表分裂
  • 语法
    ALTER TABLE identifier SPLIT PARTITION identifier
  • 示例

    执行以下SQL,创建表tb1:

    CREATE TABLE tb1(a int) PARTITION BY key(a) partitions 3;

    默认的这三个分区的名字依次是p1,p2,p3,可以通过以下语法,将p1分裂成两个分区,这两个新分区是在原p1的hash空间范围内将其按hash空间范围一分为二:

    ALTER TABLE tb1 SPLIT PARTITION p1;
热点分裂

对于Key分区的表,如果发现有热点数据(数据倾斜),PolarDB-X支持将热点的数据散列到多个分区。

  • 语法
    ALTER TABLE identifier SPLIT INTO [newPartNamePrefix]
    PARTITIONS partition_count BY HOT VALUE(value_list);
  • 示例

    执行以下SQL,创建表tb1:

    CREATE TABLE tb1 (seller_id int, order_id int) 
    PARTITION BY key (seller_id, order_id) PARTITIONS BY 3;

    假如seller_id=88是个大卖家ID,对应的数据非常多,执行以下SQL将seller_id=88的数据散列到5个新的分区:hp1,hp2,hp3,hp4,hp5,这5个分区是按照seller_id=88所对应的order_id的hash空间五等份切分。

    ALTER TABLE tb1 SPLIT INTO hp PARTITIONS 5 BY HOT VALUE(88);
热点提取

对于Key分区的表,PolarDB-X支持将热点值对应的数据提取到一个单独的分区。

  • 语法
    ALTER TABLE identifier EXTRACT TO PARTITION [newPartNamePrefix] BY HOT VALUE(value_list);
  • 示例

    执行以下SQL,创建表tb1:

    CREATE TABLE tb1 (a int, b int)
    PARTITION BY key(a, b) PARTITIONS BY 3;

    执行以下SQL,将拆分键值为(a=88,b=10)的数据,提取到一个单独的新分区:

    ALTER TABLE tb1 EXTRACT TO PARTITION BY HOT VALUE(88,10);

对于List或List column分区,PolarDB-X也支持将特定的value对应的数据提取到一个单独的分区。

  • 语法
    ALTER TABLE identifier EXTRACT TO PARTITION pnew BY [HOT] VALUE(value_list);
  • 示例

    执行以下SQL,创建表tb1:

    CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
     (PARTITION p1 VALUES IN(1, 2, 3, 4, 5, 6),
      PARTITION p2 VALUES IN(7,8,9),
      PARTITION p3 VALUES IN(default))

    执行以下SQL,将value=2提取到一个单独分区:

    ALTER TABLE tb1 EXTRACT TO PARTITION pnew BY HOT VALUE(2);

分区合并

PolarDB-X支持将多个分区(两个或者两个以上)合并成一个分区,对于Hash、Key、Range或Range column分区,只能将相邻的分区合并,对于List或List column分区,可以将任意分区合并在一起。

  • 语法
    ALTER TABLE identifier MERGE PARTITIONS partition_name,...,partition_name TO partition_name;
  • 示例

    执行以下SQL,创建表tb1:

    CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
     (PARTITION p1 VALUES LESS THAN(20),
      PARTITION p2 VALUES LESS THAN(40),
     PARTITION p3 VALUES LESS THAN(100))

    执行以下SQL,将p1和p2合并:

    ALTER TABLE tb1 MERGE PARTITIONS p1,p2 to p12
    说明 对于Hash、Key、Range或Range column分区,不支持将不相邻的两个分区合并,例如p1和p3合并到一起。

分区迁移

将分区迁移到指定的存储节点。

  • 语法
    ALTER TABLE identifier MOVE PARTITIONS partition_name[,partition_name,...] TO dn_id
  • 示例

    执行以下SQL创建tb1:

    CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
     (PARTITION p1 VALUES LESS THAN(20),
      PARTITION p2 VALUES LESS THAN(40),
      PARTITION p3 VALUES LESS THAN(100))

    执行以下SQL,将p1、p3迁移到指定的存储节点DN2(其中DN2是存储节点的ID)中:

    ALTER TABLE tb1 MOVE PARTITIONS p1,p3 to 'DN2';

增加分区

对于Range或Range column分区表,如果最后一个分区不是catch-all分区(即不是values less than (MAXVALUE)定义的分区),支持在最后一个分区后增加新分区。

对于List或List column分区表,如果原分区不包括default分区(即不包括values in (default)定义的分区),支持添加新的分区。

对于key或hash分区,不支持动态的增加分区。

对于以上提到的Range或Range column(不包含catch-all分区)、List或List column分区(不包括default分区),可以通过以下语法增加一个或多个分区:

  • 语法
    ALTER TABLE identifier ADD PARTITION (partition_definition [,partition_definition] ...)
  • 示例

    执行以下SQL,创建Range分区表tb1:

    CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
     (PARTITION p1 VALUES LESS THAN(20),
      PARTITION p2 VALUES LESS THAN(40))

    执行以下SQL,给tb1增加两个分区:

    ALTER TABLE tb1 ADD PARTITION (PARTITION p3 VALUES LESS THAN(60),
                                  PARTITION p4 VALUES LESS THAN(80))

删除分区

对于分区策略为Range、Range column、List或List column的分区,支持动态的删除分区。

  • 语法
    ALTER TABLE identifier DROP PARTITION partitiion_name [,partition_name] ...
  • 示例
    执行以下SQL,创建Range分区表tb1:
    CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
     (PARTITION p1 VALUES LESS THAN(20),
      PARTITION p2 VALUES LESS THAN(40),
      PARTITION p3 VALUES LESS THAN(60))

    通过以下SQL删除p3分区:

    ALTER TABLE tb1 DROP PARTITION p3

重命名分区

通过以下语法对现有的分区名进行重命名。

  • 语法
    ALTER TABLE identifier RENAME PARTITION old_part_name to new_part_name[, old_part_name to new_part_name]
  • 示例

    执行以下SQL,创建Range分区表tb1:

    CREATE TABLE tb1(a int) PARTITION BY RANGE(a)
     (PARTITION p1 VALUES LESS THAN(20),
      PARTITION p2 VALUES LESS THAN(40),
      PARTITION p3 VALUES LESS THAN(60))

    执行以下SQL,将p2、p3重命名为p20、p30:

    ALTER TABLE tb1 RENAME PARTITION p2 to p20, p3 to p30

修改分区值

对于分区策略为List或List column的分区表,支持通过以下语法修改分区值。

  • 语法
    ALTER TABLE identifier MODIFY PARTITION partition_name ADD/DROP VALUES (value_list)
  • 示例

    执行以下SQL,创建List分区表tb1:

    CREATE TABLE tb1(a int) PARTITION BY List(a)
     (PARTITION p1 VALUES IN(1, 2, 3, 4, 5, 6),
      PARTITION p2 VALUES IN(7,8,9),
      PARTITION p3 VALUES IN(10,11,12))

    执行以下SQL将9从p2中删除,给p3增加两个分区值:

    ALTER TABLE tb1 MODIFY PARTITION p2 DROP VALUES(9);
    ALTER TABLE tb1 MODIFY PARTITION p2 ADD VALUES(13,14);

关于全局二级索引

以上的所有操作同样适用于全局二级索引表,只需要将表名替换为全局二级索引的逻辑名字。

示例

执行以下SQL,创建表tb1:

CREATE TABLE tb1(a int,b int, global index g1(b) partition by key(b) partitions 3)
PARTITION BY RANGE(a)
 (PARTITION p1 VALUES LESS THAN(20),
  PARTITION p2 VALUES LESS THAN(40),
  PARTITION p3 VALUES LESS THAN(60))

tb1有一个全局二级索引,名字是g1,它的逻辑名字是tb1.g1,执行以下SQL将tb1.g1的分区p1做分裂操作:

ALTER TABLE tb1.g1 SPLIT PARTITION p1