分区表

一张表内的数据过多时,就会严重影响到数据的查询和操作效率。openGauss支持把一张表从逻辑上分成多个小的分片,从而避免一次处理大量数据,提高处理效率。

openGauss数据库支持这些划分类型:

  • 范围分区表:指定一个或多个列划分为多个范围,每个范围创建一个分区,用来存储相应的数据。例如可以采用日期划分范围,将销售数据按照月份进行分区。
  • 列表分区表:直接按照一个列上的值来划分出分区。例如可以采用销售门店划分销售数据。
  • 间隔分区表:是一种特殊的范围分区,新增了间隔值定义。当插入记录找不到匹配的分区时可以根据间隔值自动创建分区。
  • 哈希分区表:根据表的一列,为每个分区指定模数和余数,将要插入表的记录划分到对应的分区中。

分区表的操作除了创建之外还有:

  • 查询分区表:按照分区名或者分区中的值查询数据。
  • 导入数据:直接导入数据或从现有表格中导入。
  • 修改分区表:包括增加分区、删除分区、切割分区、合并分区,以及修改分区名称等。
  • 删除分区表:与删除普通表格相同。

范围分区表的分类

范围分区表按照划分范围的方式,分为以下类别:

创建VALUES LESS THAN范围分区表语法格式

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. )
5. PARTITION BY RANGE (partition_key)
6. (
7. PARTITION partition_name VALUES LESS THAN (partition_value | MAXVALUE})
8. [, ... ]
9. );

创建VALUES LESS THAN范围分区表参数说明

  • partition_table_name

分区表的名称。 - column_name

新表中要创建的字段名。 - data_type

字段的数据类型。 - partition_key

partition_key为分区键的名称。

对于从句是VALUE LESS THAN的语法格式,范围分区策略的分区键最多支持4列。 - partition_name

partition_name为范围分区的名称。 - VALUES LESS THAN

分区中的数值必须小于上边界值。 - partition_value

partition_value为范围分区的上边界,取值依赖于partition_key的类型。 - MAXVALUE

MAXVALUE表示分区的上边界,它通常用于设置最后一个范围分区的上边界。

创建VALUES LESS THAN范围分区表示例

示例1:创建范围分区表sales_table,含有4个分区,分区键为DATE类型。分区的范围分别为:sales_date<2021-04-01,2021-04-01<= sales_date<2021-07-01,2021-07-01<=sales_date< 2021-10-01,2021-10-01 <= sales_date< MAXVALUE。

1. --创建分区表sales_table。
2. openGauss=# CREATE TABLE sales_table
3. (
4. order_no              INTEGER          NOT NULL,
5. goods_name            CHAR(20)         NOT NULL,
6. sales_date            DATE             NOT NULL,
7. sales_volume          INTEGER,
8. sales_store           CHAR(20)
9. )
10. PARTITION BY RANGE(sales_date)
11. (
12. PARTITION season1 VALUES LESS THAN('2021-04-01 00:00:00'),
13. PARTITION season2 VALUES LESS THAN('2021-07-01 00:00:00'),
14. PARTITION season3 VALUES LESS THAN('2021-10-01 00:00:00'),
15. PARTITION season4 VALUES LESS THAN(MAXVALUE)
16. );
17. -- 数据插入分区season1
18. openGauss=# INSERT INTO sales_table VALUES(1, 'jacket', '2021-01-10 00:00:00', 3,'Alaska');

20. -- 数据插入分区season2
21. openGauss=# INSERT INTO sales_table VALUES(2, 'hat', '2021-05-06 00:00:00', 5,'Clolorado');

23. -- 数据插入分区season3
24. openGauss=# INSERT INTO sales_table VALUES(3, 'shirt', '2021-09-17 00:00:00', 7,'Florida');

26. -- 数据插入分区season4
27. openGauss=# INSERT INTO sales_table VALUES(4, 'coat', '2021-10-21 00:00:00', 9,'Hawaii');

查询分区表语法格式

1. SELECT * FROM partition_table_name PARTITION { ( partition_name ) | FOR (  partition_value [, ...] ) }

查询分区表参数说明

  • partition_table_name

分区表的名称。 - partition_name

partition_name为分区的名称。 - partition_value

用于指定分区的值。PARTITION FOR子句指定的值所在的分区,就是进行查询的分区。

查询分区表语法示例

示例2:查询示例1中建立的分区表sales_table。

1. --查询sales_table的数据。
2. openGauss=# SELECT * FROM sales_table;
3. order_no |      goods_name      |     sales_date      | sales_volume |     sale
4. s_store
5. ----------+----------------------+---------------------+--------------+---------
6. -------------
7. 1 | jacket               | 2021-01-10 00:00:00 |            3 | Alaska

9. 2 | hat                  | 2021-05-06 00:00:00 |            5 | Clolorado

11. 3 | shirt                | 2021-09-17 00:00:00 |            7 | Florida

13. 4 | coat                 | 2021-10-21 00:00:00 |            9 | Hawaii

15. (4 rows)

17. --查询sales_table的4季度数据。这里采用“sales_table PARTITION (season4);”来引用第4季度数据所在分区。
18. openGauss=# SELECT * FROM sales_table PARTITION (season4);
19. order_no |      goods_name      |     sales_date      | sales_volume |     sales_store
20. ----------+----------------------+---------------------+--------------+----------------------
21. 4 | coat                 | 2021-10-21 00:00:00 |            9 | Hawaii
22. (1 row)

24. --查询sales_table的1季度数据。这里采用“sales_table PARTITION FOR ('2021-3-21 00:00:00')”来引用第1季度数据所在分区。其中的'2021-3-21 00:00:00'处于第1季度所在分区。
25. openGauss=# SELECT * FROM sales_table PARTITION FOR ('2021-3-21 00:00:00');
26. order_no |      goods_name      |     sales_date      | sales_volume |     sales_store
27. ----------+----------------------+---------------------+--------------+----------------------
28. 1 | jacket               | 2021-01-10 00:00:00 |            3 | Alaska
29. (1 row)

创建START END范围分区表语法格式

START END范围分区表有多种表达方式,而且这些方式可以在一个分区表内组合使用。

  • 方式一:START(partition_value) END (partition_value | MAXVALUE)方式

1. CREATE TABLE partition_table_name 2. ( [column_name data_type ] 3. [, ... ] 4. ) 5. PARTITION BY RANGE (partition_key) 6. ( 7. PARTITION partition_name START(partition_value) END (partition_value | MAXVALUE) 8. [, ... ] 9. ); - 方式二:START(partition_value)方式

1. CREATE TABLE partition_table_name 2. ( [column_name data_type ] 3. [, ... ] 4. ] ) 5. PARTITION BY RANGE (partition_key) 6. ( 7. PARTITION partition_name START(partition_value) 8. [, ... ] 9. ); - 方式三:END(partition_value | MAXVALUE)方式

1. CREATE TABLE partition_table_name 2. ( [column_name data_type ] 3. [, ... ] 4. ] ) 5. PARTITION BY RANGE (partition_key) 6. ( 7. PARTITION partition_name END(partition_value | MAXVALUE) 8. [, ... ] 9. ); - 方式四:START(partition_value) END (partition_value) EVERY (interval_value)方式

1. CREATE TABLE partition_table_name 2. ( [column_name data_type ] 3. [, ... ] 4. ] ) 5. PARTITION BY RANGE (partition_key) 6. ( 7. PARTITION partition_name START(partition_value) END (partition_value) EVERY (interval_value) 8. [, ... ] 9. );

创建START END范围分区表参数说明

  • partition_table_name

分区表的名称。 - column_name

新表中要创建的字段名。 - data_type

字段的数据类型。 - partition_key

partition_key为分区键的名称。

对于从句是START END的语法格式,范围分区策略的分区键仅支持1列。 - partition_name

partition_name为范围分区的名称或者范围分区的名称前缀。

  • 若该定义是“START(partition_value) END (partition_value) EVERY (interval_value)”从句,假定其中的partition_name是p1,则分区的名称依次为p1_1, p1_2, …。

    例如对于定义“PARTITION p1 START(1) END(4) EVERY(1)”,则生成的分区是:[1, 2), [2, 3) 和 [3, 4),名称依次为p1_1, p1_2和p1_3,即此处的p1是名称前缀。 - 若该定义是第一个分区定义,且该定义有START值,则范围(MINVALUE, START)将自动作为第一个实际分区,其名称为p1_0,然后该定义语义描述的分区名称依次为p1_1, p1_2, …。

    例如对于完整定义“PARTITION p1 START(1), PARTITION p2 START(2)”,生成的分区是:(MINVALUE, 1), [1, 2) 和 [2, MAXVALUE),其名称依次为p1_0, p1_1和p2,即此处p1是名称前缀,p2是分区名称。这里MINVALUE表示最小值。 - 其余的情况都是范围分区名称。 - VALUES LESS THAN

分区中的数值必须小于上边界值。 - partition_value

partition_value为范围分区的端点值(起始或终点),取值依赖于partition_key的类型。 - interval_value:

对[START,END) 表示的范围进行切分,interval_value是指定切分后每个分区的宽度。如果(END-START)值不能整除以EVERY值,则仅最后一个分区的宽度小于EVERY值。 - MAXVALUE

MAXVALUE表示分区的上边界,它通常用于设置最后一个范围分区的上边界。

创建START END范围分区表示例

示例3:以“START(partition_value) END (partition_value | MAXVALUE)”方式创建START END范围分区表graderecord。含有3个分区,分区键为INTEGER类型。分区的范围分别为:0<= grade<60,60<= grade<90,90<=grade< MAXVALUE。

1. --创建分区表graderecord。
2. openGauss=# CREATE TABLE graderecord
3. (
4. number INTEGER,
5. name CHAR(20),
6. class CHAR(20),
7. grade INTEGER
8. )
9. PARTITION BY RANGE(grade)
10. (
11. PARTITION pass START(60) END(90),
12. PARTITION excellent START(90) END(MAXVALUE)
13. );

15. -- 数据插入分区。
16. openGauss=# insert into graderecord values('210101','Alan','21.01',92);
17. openGauss=# insert into graderecord values('210102','Ben','21.01',62);
18. openGauss=# insert into graderecord values('210103','Brain','21.01',26);
19. openGauss=# insert into graderecord values('210204','Carl','21.02',77);
20. openGauss=# insert into graderecord values('210205','David','21.02',47);
21. openGauss=# insert into graderecord values('210206','Eric','21.02',97);
22. openGauss=# insert into graderecord values('210307','Frank','21.03',90);
23. openGauss=# insert into graderecord values('210308','Gavin','21.03',100);
24. openGauss=# insert into graderecord values('210309','Henry','21.03',67);
25. openGauss=# insert into graderecord values('210410','Jack','21.04',75);
26. openGauss=# insert into graderecord values('210311','Jerry','21.04',60);

28. --查询graderecord的数据。
29. openGauss=# SELECT * FROM graderecord;
30. number |         name         |        class         | grade
31. --------+----------------------+----------------------+-------
32. 210103 | Brain                | 21.01                |    26
33. 210205 | David                | 21.02                |    47
34. 210102 | Ben                  | 21.01                |    62
35. 210204 | Carl                 | 21.02                |    77
36. 210309 | Henry                | 21.03                |    67
37. 210410 | Jack                 | 21.04                |    75
38. 210311 | Jerry                | 21.04                |    60
39. 210101 | Alan                 | 21.01                |    92
40. 210206 | Eric                 | 21.02                |    97
41. 210307 | Frank                | 21.03                |    90
42. 210308 | Gavin                | 21.03                |   100
43. (11 rows)

45. --查询graderecord的pass分区数据。
46. openGauss=# SELECT * FROM graderecord PARTITION (pass);
47. ERROR:  partition "pass" of relation "graderecord" does not exist
48. 查询失败。
49. 原因是“PARTITION pass START(60) END(90),”是第一个分区定义,且该定义有START值,则范围(MINVALUE, 60)将自动作为第一个实际分区,其名称为“pass_0”。
50. 而该定义语义描述的“60<= grade<90”分区的名称为“pass_1”。

52. --查询graderecord的pass_0分区数据。
53. openGauss=# SELECT * FROM graderecord PARTITION (pass_0);
54. number |         name         |        class         | grade
55. --------+----------------------+----------------------+-------
56. 210103 | Brain                | 21.01                |    26
57. 210205 | David                | 21.02                |    47
58. (2 rows)

60. --查询graderecord的pass_1分区数据。
61. openGauss=# SELECT * FROM graderecord PARTITION (pass_1);
62. number |         name         |        class         | grade
63. --------+----------------------+----------------------+-------
64. 210102 | Ben                  | 21.01                |    62
65. 210204 | Carl                 | 21.02                |    77
66. 210309 | Henry                | 21.03                |    67
67. 210410 | Jack                 | 21.04                |    75
68. 210311 | Jerry                | 21.04                |    60
69. (5 rows)

71. --查询graderecord的execllent分区数据。
72. openGauss=# SELECT * FROM graderecord PARTITION (excellent);
73. number |         name         |        class         | grade
74. --------+----------------------+----------------------+-------
75. 210101 | Alan                 | 21.01                |    92
76. 210206 | Eric                 | 21.02                |    97
77. 210307 | Frank                | 21.03                |    90
78. 210308 | Gavin                | 21.03                |   100
79. (4 rows)

示例4:以“START(partition_value) END (partition_value) EVERY (interval_value)”方式创建START END范围分区表metro_ride_record。含有7个分区,分区键为INTEGER类型。总范围是ride_stations_number<21, 每3站为一个分区。

1. --创建分区表metro_ride_record。记录乘车人、上下车站点、乘坐站点数量。并按照乘坐站点数量,每3站建立一个分区。
2. openGauss=# CREATE TABLE metro_ride_record
3. (
4. record_number INTEGER,
5. name CHAR(20),
6. enter_station CHAR(20),
7. leave_station CHAR(20),
8. ride_stations_number INTEGER
9. )
10. PARTITION BY RANGE(ride_stations_number)
11. (
12. PARTITION cost START(3) END(21)  EVERY (3)
13. );

15. -- 数据插入分区。
16. openGauss=# insert into metro_ride_record values('120101','Brain','Tung Chung','Tsing Yi',2);
17. openGauss=# insert into metro_ride_record values('120102','David','Po Lam','Yau Tong',4);
18. openGauss=# insert into metro_ride_record values('120103','Ben','Yau Ma Tei','Wong Tai Sin',6);
19. openGauss=# insert into metro_ride_record values('120104','Carl','Tai Wo Hau','Prince Edward',8);
20. openGauss=# insert into metro_ride_record values('120105','Henry','Admiralty','Lai King',10);
21. openGauss=# insert into metro_ride_record values('120106','Jack','Chai Wan','Central',12);
22. openGauss=# insert into metro_ride_record values('120107','Jerry','Central','Tai Wo Hau',14);
23. openGauss=# insert into metro_ride_record values('120108','Alan','Diamond Hill','Kwai Hing',16);
24. openGauss=# insert into metro_ride_record values('120109','Eric','Jordan','Shek Kip Mei',18);
25. openGauss=# insert into metro_ride_record values('120110','Frank','Lok Fu','Sunny Bay',20);

27. --查询metro_ride_record的数据。
28. openGauss=# SELECT * FROM metro_ride_record;
29. record_number |         name         |    enter_station     |    leave_station     | ride_stations_number
30. ---------------+----------------------+----------------------+----------------------+----------------------
31. 120101 | Brain                | Tung Chung           | Tsing Yi             |                    2
32. 120102 | David                | Po Lam               | Yau Tong             |                    4
33. 120103 | Ben                  | Yau Ma Tei           | Wong Tai Sin         |                    6
34. 120104 | Carl                 | Tai Wo Hau           | Prince Edward        |                    8
35. 120105 | Henry                | Admiralty            | Lai King             |                   10
36. 120106 | Jack                 | Chai Wan             | Central              |                   12
37. 120107 | Jerry                | Central              | Tai Wo Hau           |                   14
38. 120108 | Alan                 | Diamond Hill         | Kwai Hing            |                   16
39. 120109 | Eric                 | Jordan               | Shek Kip Mei         |                   18
40. 120110 | Frank                | Lok Fu               | Sunny Bay            |                   20
41. (10 rows)

43. “PARTITION cost START(3) END(21)  EVERY (3)”是第一个分区定义,且该定义有START值,则范围(MINVALUE, 3)将自动作为第一个实际分区,其名称为“cost_0”。
44. 其余分区依次为“cost_1”、...、“cost_6”.

46. --查询metro_ride_record的cost_0分区数据。
47. openGauss=# SELECT * FROM metro_ride_record PARTITION (cost_0);
48. record_number |         name         |    enter_station     |    leave_station     | ride_stations_number
49. ---------------+----------------------+----------------------+----------------------+----------------------
50. 120101 | Brain                | Tung Chung           | Tsing Yi             |                    2
51. (1 row)

53. --查询metro_ride_record的cost_1分区数据。
54. openGauss=# SELECT * FROM metro_ride_record PARTITION (cost_1);
55. record_number |         name         |    enter_station     |    leave_station     | ride_stations_number
56. ---------------+----------------------+----------------------+----------------------+----------------------
57. 120102 | David                | Po Lam               | Yau Tong             |                    4
58. (1 row)

60. --查询metro_ride_record的cost_6分区数据。
61. openGauss=# SELECT * FROM metro_ride_record PARTITION (cost_6);
62. record_number |         name         |    enter_station     |    leave_station     | ride_stations_number
63. ---------------+----------------------+----------------------+----------------------+----------------------
64. 120109 | Eric                 | Jordan               | Shek Kip Mei         |                   18
65. 120110 | Frank                | Lok Fu               | Sunny Bay            |                   20
66. (2 rows)

示例5:以“START(partition_value) ”方式创建START END范围分区表graderecord。含有3个分区,分区键为INTEGER类型。分区的范围分别为:0<= grade<60,60<= grade<90,90<=grade< MAXVALUE。

1. --创建分区表graderecord。
2. openGauss=# CREATE TABLE graderecord
3. (
4. number INTEGER,
5. name CHAR(20),
6. class CHAR(20),
7. grade INTEGER
8. )
9. PARTITION BY RANGE(grade)
10. (
11. PARTITION pass START(60),
12. PARTITION excellent START(90)
13. );

15. -- 数据插入分区。
16. openGauss=# insert into graderecord values('210101','Alan','21.01',92);
17. openGauss=# insert into graderecord values('210102','Ben','21.01',62);
18. openGauss=# insert into graderecord values('210103','Brain','21.01',26);
19. openGauss=# insert into graderecord values('210204','Carl','21.02',77);
20. openGauss=# insert into graderecord values('210205','David','21.02',47);
21. openGauss=# insert into graderecord values('210206','Eric','21.02',97);
22. openGauss=# insert into graderecord values('210307','Frank','21.03',90);
23. openGauss=# insert into graderecord values('210308','Gavin','21.03',100);
24. openGauss=# insert into graderecord values('210309','Henry','21.03',67);
25. openGauss=# insert into graderecord values('210410','Jack','21.04',75);
26. openGauss=# insert into graderecord values('210311','Jerry','21.04',60);

29. --查询graderecord的数据。
30. openGauss=# SELECT * FROM graderecord;
31. number |         name         |        class         | grade
32. --------+----------------------+----------------------+-------
33. 210103 | Brain                | 21.01                |    26
34. 210205 | David                | 21.02                |    47
35. 210102 | Ben                  | 21.01                |    62
36. 210204 | Carl                 | 21.02                |    77
37. 210309 | Henry                | 21.03                |    67
38. 210410 | Jack                 | 21.04                |    75
39. 210311 | Jerry                | 21.04                |    60
40. 210101 | Alan                 | 21.01                |    92
41. 210206 | Eric                 | 21.02                |    97
42. 210307 | Frank                | 21.03                |    90
43. 210308 | Gavin                | 21.03                |   100
44. (11 rows)

46. --查询graderecord的pass分区数据。
47. openGauss=# SELECT * FROM graderecord PARTITION (pass);
48. ERROR:  partition "pass" of relation "graderecord" does not exist
49. 查询失败。
50. 原因是“PARTITION pass START(60),”是第一个分区定义,且该定义有START值,则范围(MINVALUE, 60)将自动作为第一个实际分区,其名称为“pass_0”。
51. 而该定义语义描述的“60<= grade<90”分区的名称为“pass_1”。

53. --查询graderecord的pass_0分区数据。
54. openGauss=# SELECT * FROM graderecord PARTITION (pass_0);
55. number |         name         |        class         | grade
56. --------+----------------------+----------------------+-------
57. 210103 | Brain                | 21.01                |    26
58. 210205 | David                | 21.02                |    47
59. (2 rows)

61. --查询graderecord的pass_1分区数据。
62. openGauss=# SELECT * FROM graderecord PARTITION (pass_1);
63. number |         name         |        class         | grade
64. --------+----------------------+----------------------+-------
65. 210102 | Ben                  | 21.01                |    62
66. 210204 | Carl                 | 21.02                |    77
67. 210309 | Henry                | 21.03                |    67
68. 210410 | Jack                 | 21.04                |    75
69. 210311 | Jerry                | 21.04                |    60
70. (5 rows)

72. --查询graderecord的execllent分区数据。
73. openGauss=# SELECT * FROM graderecord PARTITION (excellent);
74. number |         name         |        class         | grade
75. --------+----------------------+----------------------+-------
76. 210101 | Alan                 | 21.01                |    92
77. 210206 | Eric                 | 21.02                |    97
78. 210307 | Frank                | 21.03                |    90
79. 210308 | Gavin                | 21.03                |   100
80. (4 rows)

示例6:以“END(partition_value | MAXVALUE) ”方式创建START END范围分区表graderecord。含有3个分区,分区键为INTEGER类型。分区的范围分别为:0<= grade<60,60<= grade<90,90<=grade< MAXVALUE。。

1. --创建分区表graderecord。
2. openGauss=# CREATE TABLE graderecord
3. (
4. number INTEGER,
5. name CHAR(20),
6. class CHAR(20),
7. grade INTEGER
8. )
9. PARTITION BY RANGE(grade)
10. (
11. PARTITION no_pass END(60),
12. PARTITION pass END(90),
13. PARTITION excellent END(MAXVALUE)
14. );

16. -- 数据插入分区。
17. openGauss=# insert into graderecord values('210101','Alan','21.01',92);
18. openGauss=# insert into graderecord values('210102','Ben','21.01',62);
19. openGauss=# insert into graderecord values('210103','Brain','21.01',26);
20. openGauss=# insert into graderecord values('210204','Carl','21.02',77);
21. openGauss=# insert into graderecord values('210205','David','21.02',47);
22. openGauss=# insert into graderecord values('210206','Eric','21.02',97);
23. openGauss=# insert into graderecord values('210307','Frank','21.03',90);
24. openGauss=# insert into graderecord values('210308','Gavin','21.03',100);
25. openGauss=# insert into graderecord values('210309','Henry','21.03',67);
26. openGauss=# insert into graderecord values('210410','Jack','21.04',75);
27. openGauss=# insert into graderecord values('210311','Jerry','21.04',60);

30. --查询graderecord的数据。
31. openGauss=# SELECT * FROM graderecord;
32. number |         name         |        class         | grade
33. --------+----------------------+----------------------+-------
34. 210103 | Brain                | 21.01                |    26
35. 210205 | David                | 21.02                |    47
36. 210102 | Ben                  | 21.01                |    62
37. 210204 | Carl                 | 21.02                |    77
38. 210309 | Henry                | 21.03                |    67
39. 210410 | Jack                 | 21.04                |    75
40. 210311 | Jerry                | 21.04                |    60
41. 210101 | Alan                 | 21.01                |    92
42. 210206 | Eric                 | 21.02                |    97
43. 210307 | Frank                | 21.03                |    90
44. 210308 | Gavin                | 21.03                |   100
45. (11 rows)

47. --查询graderecord的no_pass分区数据。
48. openGauss=# SELECT * FROM graderecord PARTITION (no_pass);
49. number |         name         |        class         | grade
50. --------+----------------------+----------------------+-------
51. 210103 | Brain                | 21.01                |    26
52. 210205 | David                | 21.02                |    47
53. (2 rows)

55. --查询graderecord的pass分区数据。
56. openGauss=# SELECT * FROM graderecord PARTITION (pass);
57. number |         name         |        class         | grade
58. --------+----------------------+----------------------+-------
59. 210102 | Ben                  | 21.01                |    62
60. 210204 | Carl                 | 21.02                |    77
61. 210309 | Henry                | 21.03                |    67
62. 210410 | Jack                 | 21.04                |    75
63. 210311 | Jerry                | 21.04                |    60
64. (5 rows)

66. --查询graderecord的execllent分区数据。
67. openGauss=# SELECT * FROM graderecord PARTITION (excellent);
68. number |         name         |        class         | grade
69. --------+----------------------+----------------------+-------
70. 210101 | Alan                 | 21.01                |    92
71. 210206 | Eric                 | 21.02                |    97
72. 210307 | Frank                | 21.03                |    90
73. 210308 | Gavin                | 21.03                |   100
74. (4 rows)

创建列表分区表语法格式

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. )
5. PARTITION BY LIST (partition_key)
6. (
7. PARTITION partition_name VALUES (list_values_clause)
8. [, ... ]
9. );

创建列表分区表参数说明

  • partition_table_name

分区表的名称。 - column_name

新表中要创建的字段名。 - data_type

字段的数据类型。 - partition_key

partition_key为分区键的名称。

列表分区策略的分区键仅支持1列。 - partition_name

partition_name为范围分区的名称。 - list_values_clause

对应分区存在的一个或者多个键值。多个键值之间以逗号分隔。 - VALUES (DEFAULT)

加入的数据如有“list_values_clause”中未列出的键值,存放在VALUES (DEFAULT)对应的分区。 - MAXVALUE

MAXVALUE表示分区的上边界,它通常用于设置最后一个范围分区的上边界。

创建列表分区表示例

示例7:创建列表分区表graderecord。含有4个分区,分区键为CHAR类型。分区的范围分别为:21.01,21.02,21.03,21.04。

1. --创建分区表graderecord。
2. openGauss=# CREATE TABLE graderecord
3. (
4. number INTEGER,
5. name CHAR(20),
6. class CHAR(20),
7. grade INTEGER
8. )
9. PARTITION BY LIST(class)
10. (
11. PARTITION class_01 VALUES ('21.01'),
12. PARTITION class_02 VALUES ('21.02'),
13. PARTITION class_03 VALUES ('21.03'),
14. PARTITION class_04 VALUES ('21.04')
15. );

17. -- 数据插入分区。
18. openGauss=# insert into graderecord values('210101','Alan','21.01',92);
19. openGauss=# insert into graderecord values('210102','Ben','21.01',62);
20. openGauss=# insert into graderecord values('210103','Brain','21.01',26);
21. openGauss=# insert into graderecord values('210204','Carl','21.02',77);
22. openGauss=# insert into graderecord values('210205','David','21.02',47);
23. openGauss=# insert into graderecord values('210206','Eric','21.02',97);
24. openGauss=# insert into graderecord values('210307','Frank','21.03',90);
25. openGauss=# insert into graderecord values('210308','Gavin','21.03',100);
26. openGauss=# insert into graderecord values('210309','Henry','21.03',67);
27. openGauss=# insert into graderecord values('210410','Jack','21.04',75);
28. openGauss=# insert into graderecord values('210311','Jerry','21.04',60);

31. --查询graderecord的数据。
32. openGauss=# SELECT * FROM graderecord;
33. number |         name         |        class         | grade
34. --------+----------------------+----------------------+-------
35. 210410 | Jack                 | 21.04                |    75
36. 210311 | Jerry                | 21.04                |    60
37. 210307 | Frank                | 21.03                |    90
38. 210308 | Gavin                | 21.03                |   100
39. 210309 | Henry                | 21.03                |    67
40. 210204 | Carl                 | 21.02                |    77
41. 210205 | David                | 21.02                |    47
42. 210206 | Eric                 | 21.02                |    97
43. 210101 | Alan                 | 21.01                |    92
44. 210102 | Ben                  | 21.01                |    62
45. 210103 | Brain                | 21.01                |    26
46. (11 rows)

48. --查询graderecord的class_01分区数据。
49. openGauss=# SELECT * FROM graderecord PARTITION (class_01);
50. number |         name         |        class         | grade
51. --------+----------------------+----------------------+-------
52. 210101 | Alan                 | 21.01                |    92
53. 210102 | Ben                  | 21.01                |    62
54. 210103 | Brain                | 21.01                |    26
55. (3 rows)

57. --查询graderecord的class_04分区数据。
58. openGauss=# SELECT * FROM graderecord PARTITION (class_04);
59. number |         name         |        class         | grade
60. --------+----------------------+----------------------+-------
61. 210410 | Jack                 | 21.04                |    75
62. 210311 | Jerry                | 21.04                |    60
63. (2 rows)

创建间隔分区表语法格式

间隔分区是在范围分区的基础上,增加了间隔值“PARTITION BY RANGE (partition_key)”的定义。

VALUES LESS THAN间隔分区语法格式:

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. )
5. PARTITION BY RANGE (partition_key)
6. (
7. INTERVAL ('interval_expr')
8. PARTITION partition_name VALUES LESS THAN (partition_value | MAXVALUE})
9. [, ... ]
10. );

START END间隔分区表语法格式:

方式一:START(partition_value) END (partition_value | MAXVALUE)方式

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. )
5. PARTITION BY RANGE (partition_key)
6. (
7. INTERVAL ('interval_expr')
8. PARTITION partition_name START(partition_value) END (partition_value | MAXVALUE)
9. [, ... ]
10. );

方式二:START(partition_value) END (partition_value) EVERY (interval_value)方式

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. ] )
5. PARTITION BY RANGE (partition_key)
6. (
7. PARTITION partition_name START(partition_value) END (partition_value) EVERY (interval_value)
8. [, ... ]
9. );

方式三:START(partition_value)方式

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. ] )
5. PARTITION BY RANGE (partition_key)
6. (
7. INTERVAL ('interval_expr')
8. PARTITION partition_name START(partition_value)
9. [, ... ]
10. );

方式四:END(partition_value | MAXVALUE)方式

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. ] )
5. PARTITION BY RANGE (partition_key)
6. INTERVAL ('interval_expr')
7. (
8. PARTITION partition_name END(partition_value | MAXVALUE)
9. [, ... ]
10. );

间隔分区表参数说明

  • INTERVAL (‘interval_expr’)

间隔分区定义信息。只支持TIMESTAMP[(p)] [WITHOUT TIME ZONE]、TIMESTAMP[(p)] [WITH TIME ZONE]、DATE数据类型。 - interval_expr自动创建分区的间隔,例如:

自动创建分区的间隔,例如:1 day、1 month。 - partition_name

partition_name为范围分区的名称。

系统自动建立的分区按照建立的先后顺序,依次命名为:sys_p1、sys_p2、sys_p3…

间隔分区表语法示例

示例8:间隔分区表sales_table。

1. --创建分区表sales_table。
2. openGauss=# CREATE TABLE sales_table
3. (
4. order_no              INTEGER          NOT NULL,
5. goods_name            CHAR(20)         NOT NULL,
6. sales_date            DATE             NOT NULL,
7. sales_volume          INTEGER,
8. sales_store           CHAR(20)
9. )
10. PARTITION BY RANGE(sales_date)
11. INTERVAL ('1 month')
12. (
13. PARTITION start VALUES LESS THAN('2021-01-01 00:00:00'),
14. PARTITION later VALUES LESS THAN('2021-01-10 00:00:00')
15. );
16. -- 数据插入分区later
17. openGauss=# INSERT INTO sales_table VALUES(1, 'jacket', '2021-01-8 00:00:00', 3,'Alaska');

19. -- 不在已有分区的数据插入,系统会新建分区sys_p1。
20. openGauss=# INSERT INTO sales_table VALUES(2, 'hat', '2021-04-06 00:00:00', 255,'Clolorado');

22. -- 不在已有分区的数据插入,系统会新建分区sys_p2。
23. openGauss=# INSERT INTO sales_table VALUES(3, 'shirt', '2021-11-17 00:00:00', 7000,'Florida');

25. -- 数据插入分区start
26. openGauss=# INSERT INTO sales_table VALUES(4, 'coat', '2020-10-21 00:00:00', 9000,'Hawaii');

28. --查询sales_table的数据。
29. openGauss=# SELECT * FROM sales_table;
30. order_no |      goods_name      |     sales_date      | sales_volume |     sales_store
31. ----------+----------------------+---------------------+--------------+----------------------
32. 4 | coat                 | 2020-10-21 00:00:00 |         9000 | Hawaii
33. 1 | jacket               | 2021-01-08 00:00:00 |            3 | Alaska
34. 2 | hat                  | 2021-04-06 00:00:00 |          255 | Clolorado
35. 3 | shirt                | 2021-11-17 00:00:00 |         7000 | Florida
36. (4 rows)

38. --查询sales_table的start分区数据。这里采用“sales_table PARTITION (start);”来引用分区。
39. openGauss=# SELECT * FROM sales_table PARTITION (start);
40. order_no |      goods_name      |     sales_date      | sales_volume |     sales_store
41. ----------+----------------------+---------------------+--------------+----------------------
42. 4 | coat                 | 2020-10-21 00:00:00 |         9000 | Hawaii
43. (1 row)

45. --查询sales_table的later分区数据。这里采用“sales_table PARTITION (later);”来引用分区。
46. openGauss=# SELECT * FROM sales_table PARTITION (later);
47. order_no |      goods_name      |     sales_date      | sales_volume |     sales_store
48. ----------+----------------------+---------------------+--------------+----------------------
49. 1 | jacket               | 2021-01-08 00:00:00 |            3 | Alaska
50. (1 row)

52. --查询sales_table的sys_p1分区数据。这里采用“sales_table PARTITION (sys_p1);”来引用分区。
53. openGauss=# SELECT * FROM sales_table PARTITION (sys_p1);
54. order_no |      goods_name      |     sales_date      | sales_volume |     sales_store
55. ----------+----------------------+---------------------+--------------+----------------------
56. 2 | hat                  | 2021-04-06 00:00:00 |          255 | Clolorado
57. (1 row)

59. --查询sales_table的sys_p2分区数据。这里采用“sales_table PARTITION (sys_p2);”来引用分区。
60. openGauss=# SELECT * FROM sales_table PARTITION (sys_p2);
61. order_no |      goods_name      |     sales_date      | sales_volume |     sales_store
62. ----------+----------------------+---------------------+--------------+----------------------
63. 3 | shirt                | 2021-11-17 00:00:00 |         7000 | Florida
64. (1 row)

哈希分区表语法格式

1. CREATE TABLE partition_table_name
2. ( [column_name data_type ]
3. [, ... ]
4. )
5. PARTITION BY HASH (partition_key)
6. (PARTITION partition_name )
7. [, ... ]
8. );

哈希分区表参数说明

  • partition_table_name

分区表的名称。 - column_name

新表中要创建的字段名。 - data_type

字段的数据类型。 - partition_key

partition_key为分区键的名称。哈希分区策略的分区键仅支持1列。 - partition_name

partition_name为哈希分区的名称。希望创建几个哈希分区就给出几个分区名。

哈希分区表示例

示例9:哈希分区表hash_partition_table。

1. --创建哈希分区表hash_partition_table
2. openGauss=# create table hash_partition_table (
3. col1 int,
4. col2 int)
5. partition by hash(col1)
6. (
7. partition p1,
8. partition p2
9. );

11. -- 数据插入
12. openGauss=# INSERT INTO hash_partition_table VALUES(1, 1);
13. INSERT 0 1
14. openGauss=# INSERT INTO hash_partition_table VALUES(2, 2);
15. INSERT 0 1
16. openGauss=# INSERT INTO hash_partition_table VALUES(3, 3);
17. INSERT 0 1
18. openGauss=# INSERT INTO hash_partition_table VALUES(4, 4);
19. INSERT 0 1

21. -- 查看数据
22. openGauss=# select * from hash_partition_table partition (p1);
23. col1 | col2
24. ------+------
25. 3 |    3
26. 4 |    4
27. (2 rows)

29. openGauss=# select * from hash_partition_table partition (p2);
30. col1 | col2
31. ------+------
32. 1 |    1
33. 2 |    2
34. (2 rows)

导入数据语法格式

导入单行数据:

1. INSERT INTO partition_table_name [ ( column_name [, ...] ) ]  VALUES [ ( value )[, ...]  ];

导入结构相同的现有表格数据:

1. INSERT INTO partition_table_name SELECT * FROM  source_table_name

导入数据参数说明

  • partition_table_name

分区表的名称。 - column_name

分区表中的字段名。可省略。 - value

字段对应的值:

  • 提供了column_name值时:value子句提供的值从左到右关联到对应列。
  • 没提供column_name值时:value子句提供的值从左到右关联到partition_table_name对应列。

导入数据示例

示例10:

1. --创建分区表employees_table。
2. openGauss=# CREATE TABLE employees_table
3. (
4. employee_id              INTEGER          NOT NULL,
5. employee_name            CHAR(20)         NOT NULL,
6. onboarding_date          DATE             NOT NULL,
7. position                 CHAR(20)
8. )
9. PARTITION BY RANGE(onboarding_date)
10. (
11. PARTITION founders VALUES LESS THAN('2000-01-01 00:00:00'),
12. PARTITION senate VALUES LESS THAN('2010-01-01 00:00:00'),
13. PARTITION seniors VALUES LESS THAN('2020-01-01 00:00:00'),
14. PARTITION newcomer VALUES LESS THAN(MAXVALUE)
15. );

17. -- 数据插入分区founders
18. openGauss=# INSERT INTO  employees_table VALUES(1, 'SMITH', '1997-01-10 00:00:00','Manager');

20. -- 查看founders分区数据
21. openGauss=# select * from employees_table partition (founders);

23. -- 创建表格employees_data_table
24. openGauss=# CREATE TABLE employees_data_table
25. (
26. employee_id              INTEGER          NOT NULL,
27. employee_name            CHAR(20)         NOT NULL,
28. onboarding_date          DATE             NOT NULL,
29. position                 CHAR(20)
30. );
31. -- 插入数据
32. openGauss=# insert into employees_data_table (employee_id, employee_name, onboarding_date, position) VALUES
33. (2, 'JONES', '2001-05-06 00:00:00', 'Supervisor'),
34. (3, 'WILLIAMS', '2011-09-17 00:00:00', 'Engineer'),
35. (4, 'TAYLOR', '2021-10-21 00:00:00', 'Clerk');

37. -- 查看表格数据
38. openGauss=# select * from employees_data_table;

40. --数据导入employees_table
41. openGauss=# INSERT INTO employees_table SELECT * FROM  employees_data_table;

43. -- 查看senate分区数据
44. openGauss=# select * from employees_table partition (senate);
45. employee_id |    employee_name     |   onboarding_date   |       position
46. -------------+----------------------+---------------------+----------------------
47. 2 | JONES                | 2001-05-06 00:00:00 | Supervisor
48. (1 row)

50. -- 查看seniors分区数据
51. openGauss=# select * from employees_table partition (seniors);
52. employee_id |    employee_name     |   onboarding_date   |       position
53. -------------+----------------------+---------------------+----------------------
54. 3 | WILLIAMS             | 2011-09-17 00:00:00 | Engineer
55. (1 row)

57. -- 查看newcomer分区数据
58. openGauss=# select * from employees_table partition (newcomer);
59. employee_id |    employee_name     |   onboarding_date   |       position
60. -------------+----------------------+---------------------+----------------------
61. 4 | TAYLOR               | 2021-10-21 00:00:00 | Clerk
62. (1 row)

修改分区表语法格式

  • 删除分区:

1. ALTER TABLE partition_table_name DROP PARTITION partition_name; - 增加分区:

1. ALTER TABLE partition_table_name ADD {partition_less_than_item | partition_start_end_item| partition_list_item }; - 重命名分区:

1. ALTER TABLE partition_table_name RENAME PARTITION partition_name TO partition_new_name; - 分裂分区(指定切割点split_partition_value的语法):

1. ALTER TABLE partition_table_name SPLIT PARTITION partition_name AT ( split_partition_value ) INTO ( PARTITION partition_new_name1, PARTITION partition_new_name2); - 分裂分区(指定分区范围的语法):

1. ALTER TABLE partition_table_name SPLIT PARTITION partition_name INTO { ( partition_less_than_item [, ...] ) | ( partition_start_end_item [, ...] ) }; - 合并分区:

1. ALTER TABLE partition_table_name MERGE PARTITIONS { partition_name } [, ...] INTO PARTITION partition_name;

修改分区表参数说明

  • partition_table_name

分区表的名称。 - partition_name

partition_name为分区的名称。 - split_partition_value

切割点。 - PARTITION partition_new_name1, PARTITION partition_new_name2

按照切割点分裂出的两个分区。 - partition_less_than_item

分区项的描述语句,语法为:

1. PARTITION partition_name VALUES LESS THAN ( { partition_value | MAXVALUE } [, ...] )

用法与创建VALUES LESS THAN范围分区表语法格式中相同。 - partition_start_end_item

分区项的描述语句,语法为:

1. PARTITION partition_name { 2. {START(partition_value) END (partition_value) EVERY (interval_value)} | 3. {START(partition_value) END ({partition_value | MAXVALUE})} | 4. {START(partition_value)} | 5. {END({partition_value | MAXVALUE})}

用法与创建START END范围分区表语法格式中相同。 - partition_list_item

分区项的描述语句,语法为:

1. PARTITION partition_name VALUES (list_values_clause)

用法与创建列表分区表语法格式中相同。 - split_point_clause

分裂分区时,指定的切割点。 - partition_value

分区键值。

修改分区表示例

示例11:

1. --创建分区表employees_table。
2. openGauss=# CREATE TABLE employees_table
3. (
4. employee_id              INTEGER          NOT NULL,
5. employee_name            CHAR(20)         NOT NULL,
6. onboarding_date          DATE             NOT NULL,
7. position                 CHAR(20)
8. )
9. PARTITION BY RANGE(onboarding_date)
10. (
11. PARTITION founders VALUES LESS THAN('2000-01-01 00:00:00'),
12. PARTITION senate VALUES LESS THAN('2010-01-01 00:00:00'),
13. PARTITION seniors VALUES LESS THAN('2020-01-01 00:00:00'),
14. PARTITION newcomer VALUES LESS THAN(MAXVALUE)
15. );

17. -- 插入数据
18. openGauss=# INSERT INTO  employees_table VALUES
19. (1, 'SMITH', '1997-01-10 00:00:00','Manager'),
20. (2, 'JONES', '2001-05-06 00:00:00', 'Supervisor'),
21. (3, 'WILLIAMS', '2011-09-17 00:00:00', 'Engineer'),
22. (4, 'TAYLOR', '2021-10-21 00:00:00', 'Clerk');

24. 查看newcomer分区
25. openGauss=# SELECT * FROM employees_table PARTITION (newcomer);
26. employee_id |    employee_name     |   onboarding_date   |       position
27. -------------+----------------------+---------------------+----------------------
28. 4 | TAYLOR               | 2021-10-21 00:00:00 | Clerk
29. (1 row)

31. --删除newcomer分区。
32. openGauss=# ALTER TABLE employees_table DROP PARTITION newcomer;
33. ALTER TABLE

35. -- 查看newcomer分区数据
36. openGauss=# select * from employees_table partition (newcomer);
37. ERROR:  partition "newcomer" of relation "employees_table" does not exist

39. --增加fresh分区。
40. openGauss=# ALTER TABLE employees_table ADD PARTITION fresh VALUES LESS THAN ('2040-01-01 00:00:00');
41. ALTER TABLE

43. --以2030-01-01 00:00:00为分割点,分裂fresh分区为current、future两个分区
44. openGauss=# ALTER TABLE employees_table SPLIT PARTITION fresh AT ('2030-01-01 00:00:00') INTO (PARTITION current, PARTITION future);
45. ALTER TABLE

47. --将分区current改名为now
48. openGauss=# ALTER TABLE employees_table RENAME PARTITION current TO now;
49. ALTER TABLE

51. --将founders,senate合并为一个分区original。
52. openGauss=# ALTER TABLE  employees_table MERGE PARTITIONS founders, senate INTO PARTITION original;

删除分区表语法格式

1. DROP TABLE partition_table_name;

删除分区表参数说明

  • partition_table_name

分区表的名称。

删除分区表示例

示例12:

1. --删除分区表employees_table。
2. openGauss=# DROP TABLE employees_table;
3. DROP TABLE