
# 范围分区
范围分区（Range Partition）依据所设定的每个分区的分区键值范围，来实现数据到各个分区的映射。在实际的生产系统里，范围分区是很常用的一种分区类型，通常在以时间维度（Date、Time Stamp）描述数据场景中使用。
范围分区有两种语法格式，示例如下：
- VALUES LESS THAN的语法格式 对于从句是VALUE LESS THAN的语法格式，范围分区策略的分区键最多支持16列。
  - 单列分区键示例如下：
    ```
    gaussdb=# CREATE TABLE range_sales
    (
        product_id      INT4 NOT NULL,
        customer_id     INT4 NOT NULL,
        time            DATE,
        channel_id      CHAR(1),
        type_id         INT4,
        quantity_sold   NUMERIC(3),
        amount_sold     NUMERIC(10,2)
    )
    PARTITION BY RANGE (time)
    (
        PARTITION date_202001 VALUES LESS THAN ('2020-02-01'),
        PARTITION date_202002 VALUES LESS THAN ('2020-03-01'),
        PARTITION date_202003 VALUES LESS THAN ('2020-04-01'),
        PARTITION date_202004 VALUES LESS THAN ('2020-05-01')
    );
    gaussdb=# DROP TABLE range_sales;
    ```
    其中，名为date_202002的分区表示2020年2月的分区，将包含分区键值在2020年2月1日到2020年2月29日的数据。
    每个分区都有一个VALUES LESS子句，用于明确该分区的非包含上限值。当数据的分区键值大于或等于当前分区的该上限值时，这些数据将会被添加至下一个分区当中。除第一个分区外，其余所有分区都存在一个由前序分区的VALUES LESS子句所隐式指定的下限值。
    针对最高分区，可以定义使用MAXVALUE关键字，MAXVALUE代表着一个虚拟的无限值，在排序规则上，它的优先级高于分区键的其他任何可能取值，包括空值。
    
  
  - 多列分区键示例如下：
    ```
    gaussdb=# CREATE TABLE range_sales_with_multiple_keys
    (
        c1      INT4 NOT NULL,
        c2      INT4 NOT NULL,
        c3      CHAR(1)
    )
    PARTITION BY RANGE (c1,c2)
    (
        PARTITION p1 VALUES LESS THAN (10,10),
        PARTITION p2 VALUES LESS THAN (10,20),
        PARTITION p3 VALUES LESS THAN (20,10)
    );
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(9,5,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(9,20,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(9,21,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(10,5,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(10,15,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(10,20,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(10,21,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(11,5,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(11,20,'a');
    gaussdb=# INSERT INTO range_sales_with_multiple_keys VALUES(11,21,'a');
    gaussdb=# SELECT * FROM range_sales_with_multiple_keys PARTITION (p1);
     c1 | c2 | c3
    ----+----+----
      9 |  5 | a
      9 | 20 | a
      9 | 21 | a
     10 |  5 | a
    (4 rows)
    gaussdb=# SELECT * FROM range_sales_with_multiple_keys PARTITION (p2);
     c1 | c2 | c3
    ----+----+----
     10 | 15 | a
    (1 row)
    gaussdb=# SELECT * FROM range_sales_with_multiple_keys PARTITION (p3);
     c1 | c2 | c3
    ----+----+----
     10 | 20 | a
     10 | 21 | a
     11 |  5 | a
     11 | 20 | a
     11 | 21 | a
    (5 rows)
    gaussdb=# DROP TABLE range_sales_with_multiple_keys;
    ```
    ![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    多列分区的分区规则如下：
    1. 从第一列开始比较。
    
    2. 如果插入的当前列小于分区当前列边界值，则直接插入。
    
    3. 如果插入的当前列等于分区当前列的边界值，则比较插入值的下一列与分区下一列边界值的大小。
    
    4. 如果插入的当前列大于分区当前列的边界值，则换下一个分区进行比较。
      
   
- START END语法格式 对于从句是START END语法格式，范围分区策略的分区键最多支持1列。
  示例如下：
  ```
  -- 创建表空间。
  gaussdb=# CREATE TABLESPACE startend_tbs1 LOCATION '/home/omm/startend_tbs1';
  gaussdb=# CREATE TABLESPACE startend_tbs2 LOCATION '/home/omm/startend_tbs2';
  gaussdb=# CREATE TABLESPACE startend_tbs3 LOCATION '/home/omm/startend_tbs3';
  gaussdb=# CREATE TABLESPACE startend_tbs4 LOCATION '/home/omm/startend_tbs4';
  -- 创建临时schema。
  gaussdb=# CREATE SCHEMA tpcds;
  gaussdb=# SET CURRENT_SCHEMA TO tpcds;
  -- 创建分区表，分区键是integer类型。
  gaussdb=# CREATE TABLE tpcds.startend_pt (c1 INT, c2 INT)
  TABLESPACE startend_tbs1
  PARTITION BY RANGE (c2) (
      PARTITION p1 START(1) END(1000) EVERY(200) TABLESPACE startend_tbs2,
      PARTITION p2 END(2000),
      PARTITION p3 START(2000) END(2500) TABLESPACE startend_tbs3,
      PARTITION p4 START(2500),
      PARTITION p5 START(3000) END(5000) EVERY(1000) TABLESPACE startend_tbs4
  );
  ENABLE ROW MOVEMENT;
  -- 查看分区表信息。
  gaussdb=# SELECT relname, boundaries, spcname FROM pg_partition p JOIN pg_tablespace t ON
      p.reltablespace=t.oid and p.parentid='tpcds.startend_pt'::regclass ORDER BY 1;
  relname | boundaries | spcname
  -------------+------------+---------------
  p1_0 | {1} | startend_tbs2
  p1_1 | {201} | startend_tbs2
  p1_2 | {401} | startend_tbs2
  p1_3 | {601} | startend_tbs2
  p1_4 | {801} | startend_tbs2
  p1_5 | {1000} | startend_tbs2
  p2 | {2000} | startend_tbs1
  p3 | {2500} | startend_tbs3
  p4 | {3000} | startend_tbs1
  p5_1 | {4000} | startend_tbs4
  p5_2 | {5000} | startend_tbs4
  startend_pt | | startend_tbs1
  (12 rows)
  --删除表和Schema。
  gaussdb=# DROP TABLE tpcds.startend_pt;
  DROP TABLE
  gaussdb=# DROP SCHEMA tpcds;
  DROP SCHEMA
  ```
  
 
