1. 程式人生 > >PostgreSQL V10 分割槽表特性

PostgreSQL V10 分割槽表特性

目錄

環境

文件用途

詳細資訊

相關文件

環境

系統平臺:N/A

版本:10.3

文件用途

PostgreSQL V10 分割槽表的理解與使用

詳細資訊

分割槽表特性是PG10新加的一個很重要的特性。

之前的版本也能實現分割槽表功能,是根據“繼承表+約束+規則或觸發器”實現。

 

相對於之前的分割槽實現方式,PG10的分割槽特性有以下優勢:

 1)管理分割槽方便

 2)資料插入效率高

 

事實上,PG10的分割槽特性也是在內建繼承表的基礎上實現的,所以建立的分割槽實質上也是普通的表結構。

 

目前PG10支援範圍分割槽和列表分割槽,雜湊分割槽還不支援。

 

範圍分割槽:

 

PG10的分割槽表在建表語法上,主表和分割槽是單獨建立的。下面的列表分割槽也是一樣。

 

建立主表語法:

 CREATE TABLE 表名 ( [{ 列名稱 資料_型別} [, ... ] ] )

 PARTITION BY RANGE ( [{ 列名稱 } [, ...] ] );

範圍分割槽的KEY值可由多個欄位組成(最多32個欄位)。

 

建立分割槽語法:

CREATE TABLE 表名 PARTITION OF 主表 FOR VALUES

FROM{ ( 表示式 [, ...] ) | MINVALUE } [, ...]

TO { ( 表示式 [, ...] ) | MAXVALUE } [, ...] [ TABLESPACE 表空間名 ];

 

引數說明:

// FROM ... TO 表示分割槽的起始值和結束值。

// MINVALUE / MAXVALUE 表示無限小值和無限大值。

// 預設FROM後面的值是包括值分割槽的約束內,TO後面的值不包括。

 

示例:

 

postgres=# create table test(n int) partition by range(n);

CREATE TABLE

postgres=# create table test_1 partition of test for values from (MINVALUE) to (10);

CREATE TABLE

postgres=# create table test_2 partition of test for values from (10) to (100);

CREATE TABLE

postgres=# create table test_3 partition of test for values from (100) to (1000);

CREATE TABLE

postgres=# create table test_4 partition of test for values from (1000) to (10000);

CREATE TABLE

 

 

postgres=# \d+ test

                                   Table "public.test"

 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Descrip

tion

--------+---------+-----------+----------+---------+---------+--------------+--------

-----

 n      | integer |           |          |         | plain   |              |

Partition key: RANGE (n)

Partitions: test_1 FOR VALUES FROM (MINVALUE) TO (10),

            test_2 FOR VALUES FROM (10) TO (100),

            test_3 FOR VALUES FROM (100) TO (1000),

            test_4 FOR VALUES FROM (1000) TO (10000)

 

postgres=# \d+ test_2

                                  Table "public.test_2"

 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Descrip

tion

--------+---------+-----------+----------+---------+---------+--------------+--------

-----

 n      | integer |           |          |         | plain   |              |

Partition of: test FOR VALUES FROM (10) TO (100)

Partition constraint: ((n IS NOT NULL) AND (n >= 10) AND (n < 100))

 

postgres=# insert into test select generate_series(0, 9999);INSERT 0 10000

postgres=#  explain analyze select * from test;

                                                  

QUERY PLAN                         

                          

-------------------------------------------------------------------------------------

--------------------------

 Append  (cost=0.00..248.50 rows=17850 width=4) (actual time=0.010..11.248 rows=10000

 loops=1)

   ->  Seq Scan on test_1  (cost=0.00..35.50 rows=2550 width=4) (actual time=0.009..0

.014 rows=10 loops=1)

   ->  Seq Scan on test_2  (cost=0.00..35.50 rows=2550 width=4) (actual time=0.012..0

.044 rows=90 loops=1)

   ->  Seq Scan on test_3  (cost=0.00..35.50 rows=2550 width=4) (actual time=0.025..0

.441 rows=900 loops=1)

   ->  Seq Scan on test_4  (cost=0.00..142.00 rows=10200 width=4) (actual time=0.026.

.4.317 rows=9000 loops=1)

 Planning time: 0.248 ms

 Execution time: 14.503 ms

(7 rows)

 

列表分割槽:

 

列表的KEY只支援一個欄位。

 

建立主表語法:

 CREATE TABLE 表名 ( [{ 列名稱 資料_型別} [, ... ] ] )

 PARTITION BY LIST( { 列名稱 } );

 

建立分割槽語法:

CREATE TABLE 表名 PARTITION OF 主表 FOR VALUES

IN ( 表示式 [, ...] ) [ TABLESPACE 表空間名 ];

 

示例:

 

postgres=# CREATE TABLE sales (product_id int, saleroom int, province text) PARTITION BY LIST(province);

CREATE TABLE

postgres=# CREATE TABLE sales_east PARTITION OF sales FOR VALUES IN ('山東','江蘇',' 上海');

CREATE TABLE

postgres=# CREATE TABLE sales_west PARTITION OF sales FOR VALUES IN ('山西','陝西',' 四川');

CREATE TABLE

postgres=# CREATE TABLE sales_north PARTITION OF sales FOR VALUES IN ('北京','河北','遼寧');

CREATE TABLE

postgres=# CREATE TABLE sales_south PARTITION OF sales FOR VALUES IN ('廣東','福建');CREATE TABLE

 

postgres=# \d+ sales

                                     Table "public.sales"

   Column   |  Type   | Collation | Nullable | Default | Storage  | Stats target | De

scription

------------+---------+-----------+----------+---------+----------+--------------+---

----------

 product_id | integer |           |          |         | plain    |              |

 saleroom   | integer |           |          |         | plain    |              |

 province   | text    |           |          |         | extended |              |

Partition key: LIST (province)

Partitions: sales_east FOR VALUES IN ('山東', '江蘇', '上海'),

            sales_north FOR VALUES IN ('北京', '河北', '遼寧'),

            sales_south FOR VALUES IN ('廣東', '福建'),

            sales_west FOR VALUES IN ('山西', '陝西', '四川')

 

postgres=# \d+ sales_east

                                   Table "public.sales_east"

   Column   |  Type   | Collation | Nullable | Default | Storage  | Stats target | De

scription

------------+---------+-----------+----------+---------+----------+--------------+---

----------

 product_id | integer |           |          |         | plain    |              |

 saleroom   | integer |           |          |         | plain    |              |

 province   | text    |           |          |         | extended |              |

Partition of: sales FOR VALUES IN ('山東', '江蘇', '上海')

Partition constraint: ((province IS NOT NULL) AND (province = ANY (ARRAY['山東'::text

, '江蘇'::text, '上海'::text])))

 

postgres=# insert into sales values (1001, 2345234, '山東');

INSERT 0 1

postgres=# insert into sales values (1002, 23233, '河北');

INSERT 0 1

postgres=# insert into sales values (1001, 4357233, '廣東');

INSERT 0 1

postgres=# insert into sales values (1002, 67233, '陝西');

INSERT 0 1

 

postgres=#  explain analyze select * from sales;

                                                   

QUERY PLAN                        

                           

-------------------------------------------------------------------------------------

---------------------------

 Append  (cost=0.00..88.00 rows=4800 width=40) (actual time=0.009..0.023 rows=4 loops

=1)

   ->  Seq Scan on sales_east  (cost=0.00..22.00 rows=1200 width=40) (actual time=0.0

08..0.009 rows=1 loops=1)

   ->  Seq Scan on sales_west  (cost=0.00..22.00 rows=1200 width=40) (actual time=0.0

03..0.003 rows=1 loops=1)

   ->  Seq Scan on sales_north  (cost=0.00..22.00 rows=1200 width=40) (actual time=0.

003..0.003 rows=1 loops=1)

   ->  Seq Scan on sales_south  (cost=0.00..22.00 rows=1200 width=40) (actual time=0.

002..0.003 rows=1 loops=1)

 Planning time: 0.305 ms

 Execution time: 0.054 ms

(7 rows)

 

獲取系統資訊(系統表):

pg_partitioned_table 記錄主表資訊的系統表:

 528.png

 

 

分割槽的資訊記錄在pg_class相關的欄位中:

 529.png

 

獲取系統資訊(分割槽函式):

 

 

pg_get_partkeydef (Oid  relid) -- 根據主表OID返回分割槽型別及KEY:

postgres=# select pg_get_partkeydef('test'::regclass);

 pg_get_partkeydef

-------------------

 RANGE (n)

(1 row)

 

pg_get_partition_constraintdef (Oid  relid) -- 根據分割槽OID獲取分割槽約束條件:

postgres=# select pg_get_partition_constraintdef('test_1'::regclass);

 pg_get_partition_constraintdef

--------------------------------

 ((n IS NOT NULL) AND (n < 10))

(1 row)

 

 

其他操作—ATTACH操作:

ATTACH操作是把和主表有相同表結構的主表變成該主表的一個分割槽:

範圍分割槽:

ALTER TABLE 主表名 ATTACH PARTITION 表名 FOR VALUES

FROM{ ( 表示式 [, ...] ) | MINVALUE  } [, ...]

TO { ( 表示式 [, ...] ) | MAXVALUE } [, ...];

 

列表分割槽:

ALTER TABLE 主表名 ATTACH PARTITION 表名 FOR VALUES

IN ( 表示式 [, ...] );

 

更多示例請登入【瀚高技術支援平臺】檢視

https://support.highgo.com/#/index/docContent/a1b0eba8026447db