PostgreSQL中的分区表

参考:https://www.xmmup.com/pgzhongdefenqubiao.html#PG_11xin_te_xing

PostgreSQL分区的意思是把逻辑上的一个大表分割成物理上的几块。分区不仅能带来访问速度的提升,关键的是,它能带来管理和维护上的方便。

分区表的具体好处:

  • 某些类型的查询性能可以得到极大提升
  • 更新的性能也可以得到提升,因为表的每块的索引要比在整个数据集上的索引要小。如果索引不能全部放在内存里,那么在索引上的读和写都会产生更多的磁盘访问
  • 批量删除可以用简单的删除某个分区来实现
  • 可以将很少用的数据移动到便宜、转速慢的存储介质上

PG10版本后可以通过声明式分区进行创建分区表,就是通过相应的DDL语句来创建分区表。

注意:

  • 主表和分区表分别单独创建
  • 范围分区支持多个字段组成的KEY
  • 列表分区的KEY只能有一个字段

创建主表的语法

CREATE TABLE 表名( [列名称 数据类型]...)
PARTITION BY RANG ([列名称]...)
--范围分区的KEY值可由多个字段组成(最多32个字段)。

创建分区表语法:

CREATE TABLE 表名 PARTITION of 主表 FOR VALUES
FROM (表达式) TO (表达式)

范围分区

create table tbp(n int, t text) partition by range(n); create table tbp_1 partition of tbp for values from (MINVALUE) to (10); create table tbp_2 partition of tbp for values from (10) to (100); create table tbp_3 partition of tbp for values from (100) to (1000); create table tbp_4 partition of tbp for values from (1000) to (MAXVALUE);postgres=# \dList of relationsSchema | Name  |       Type        |  Owner
--------+-------+-------------------+----------public | tbp   | partitioned table | postgrespublic | tbp_1 | table             | postgrespublic | tbp_2 | table             | postgrespublic | tbp_3 | table             | postgrespublic | tbp_4 | table             | postgres
(5 rows)postgres=# select * from pg_partitioned_table;partrelid | partstrat | partnatts | partdefid | partattrs | partclass | partcollation | partexprs
-----------+-----------+-----------+-----------+-----------+-----------+---------------+-----------16384 | r         |         1 |         0 | 1         | 1978      | 0             |
(1 row)postgres=# \d+ tbpPartitioned table "public.tbp"Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------n      | integer |           |          |         | plain    |              | t      | text    |           |          |         | extended |              |
Partition key: RANGE (n)
Partitions: tbp_1 FOR VALUES FROM (MINVALUE) TO (10),tbp_2 FOR VALUES FROM (10) TO (100),tbp_3 FOR VALUES FROM (100) TO (1000),tbp_4 FOR VALUES FROM (1000) TO (MAXVALUE)
-- 查询分区类型和KEY
postgres=# SELECT pg_get_partkeydef('tbp'::regclass); pg_get_partkeydef
-------------------RANGE (n)
(1 row)-- 获取分区范围
postgres=# SELECT pg_get_partition_constraintdef('tbp_1'::regclass) ;pg_get_partition_constraintdef
--------------------------------((n IS NOT NULL) AND (n < 10))
(1 row)

多个KEY

postgres=# create table test(n1 int, n2 int) partition by range(n1, n2);
CREATE TABLE
postgres=# create table test_1 partition of test for values from (0, 0) to (10, 100);
CREATE TABLE
postgres=# \d+ test_1Table "public.test_1"Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------n1     | integer |           |          |         | plain   |              | n2     | integer |           |          |         | plain   |              |
Partition of: test FOR VALUES FROM (0, 0) TO (10, 100)
Partition constraint: ((n1 IS NOT NULL) AND (n2 IS NOT NULL) AND ((n1 > 0) OR ((n1 = 0) AND (n2 >= 0))) AND ((n1 < 10) OR ((n1 = 10) AND (n2 < 100))))
Access method: heap

列表分区

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=# \dtList of relationsSchema |    Name     |       Type        |  Owner
--------+-------------+-------------------+----------public | sales       | partitioned table | postgrespublic | sales_east  | table             | postgrespublic | sales_north | table             | postgrespublic | sales_south | table             | postgrespublic | sales_west  | table             | postgres
(5 rows)
postgres=# insert into sales values(1,1,'山东'),(2,2,'山西'),(3,3,'北京'),(4,4,'广东');
INSERT 0 4
postgres=# select * from sales;product_id | saleroom | province
------------+----------+----------1 |        1 | 山东3 |        3 | 北京2 |        2 | 山西4 |        4 | 广东
(4 rows)postgres=# select * from sales_east;product_id | saleroom | province
------------+----------+----------1 |        1 | 山东
(1 row)postgres=# select * from sales_west;product_id | saleroom | province
------------+----------+----------2 |        2 | 山西
(1 row)

绑定分区

分区表支持把普通表绑定成父表的一个分区,也支持把分区绑定为普通表。

若普通表中有数据,ATTACH操作时,默认会做数据校验。

postgres=# CREATE TABLE sales_foreign (like sales);
CREATE TABLE
-- 绑定分区
postgres=# ALTER TABLE sales ATTACH PARTITION sales_foreign FOR VALUES IN('美国','日本');
ALTER TABLE
postgres=# \d+ salesPartitioned table "public.sales"Column   |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description
------------+---------+-----------+----------+---------+----------+--------------+-------------product_id | integer |           |          |         | plain    |              | saleroom   | integer |           |          |         | plain    |              | province   | text    |           |          |         | extended |              |
Partition key: LIST (province)
Partitions: sales_east FOR VALUES IN ('山东', '江苏', '上海'),sales_foreign FOR VALUES IN ('美国', '日本'),sales_north FOR VALUES IN ('北京', '河北', '辽宁'),sales_south FOR VALUES IN ('广东', '福建'),sales_west FOR VALUES IN ('山西', '陕西', '四川')-- 解除绑定
postgres=# ALTER TABLE sales DETACH PARTITION sales_foreign;
ALTER TABLE
postgres=# \d+ salesPartitioned table "public.sales"Column   |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description
------------+---------+-----------+----------+---------+----------+--------------+-------------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 ('山西', '陕西', '四川')

查询分区表

获取系统信息(系统表)

pg_partitioned_table记录主表信息的系统表

名称 类型 引用 描述
partrelid oid pg_class.oid 这个分区表的pg_class项的OID
partstrat char 分区策略;h = 哈希分区表,l = 列表分区表,r = 范围分区表
partnatts int2 分区键中的列数
partdefid oid pg_class.oid 这个分区表的默认分区的pg_class项的OID,如果这个分区表没有默认分区则为零。
partattrs int2vector pg_attribute.attnum 这是一个长度为partnatts值的数组,它指示哪些表列是分区键的组成部分。例如,值1 3表示第一个和第三个表列组成了分区键。这个数组中的零表示对应的分区键列是一个表达式而不是简单的列引用。
partclass oidvector pg_opclass.oid 对于分区键中的每一个列,这个域包含要使用的操作符类的OID。详见pg_opclass
partcollation oidvector pg_opclass.oid 对于分区键中的每一个列,这个域包含要用于分区的排序规则的OID,如果该列不是一种可排序数据类型则为零。
partexprs pg_node_tree 非简单列引用的分区键列的表达式树(以nodeToString()的表达方式)。这是一个列表,partattrs中每一个零项都有一个元素。如果所有分区键列都是简单列引用,则这个域为空。

分区的信息记录在pg_class相关的字段中

名称 类型 引用 描述
relispartition boolean 表是否为分区(TRUE 是)
relpartbound pg_node_tree 分区约束

hash分区

hash分区语法

--主表
CREATE TABLE TABLE_NAME (COLUMN_NAME DATA_TYPE)
PARTITION BY HASH (column_name)--分区表
CREATE TABLE table_name
PARTITION OF parent_table
FOR VALUES WITH (modulus numeric_literal, REMAINDER numeric_literal)

哈希分区支持多列分区。示例:

create table test_hash_key(x int, y int) partition by hash(x,y);
create table test_hash_key_1 partition of test_hash_key for values with(modulus 2, remainder 0);
create table test_hash_key_2 partition of test_hash_key for values with(modulus 2, remainder 1);
postgres=# \d+ test_hash_keyPartitioned table "public.test_hash_key"Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------x      | integer |           |          |         | plain   |              | y      | integer |           |          |         | plain   |              |
Partition key: HASH (x, y)
Partitions: test_hash_key_1 FOR VALUES WITH (modulus 2, remainder 0),test_hash_key_2 FOR VALUES WITH (modulus 2, remainder 1)postgres=#
postgres=# \d+ test_hash_key_1Table "public.test_hash_key_1"Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------x      | integer |           |          |         | plain   |              | y      | integer |           |          |         | plain   |              |
Partition of: test_hash_key FOR VALUES WITH (modulus 2, remainder 0)
Partition constraint: satisfies_hash_partition('16450'::oid, 2, 0, x, y)
Access method: heap

默认分区

PG11新特性,防止插入失败,对于不符合分区约束的数据会插入到默认分区。目前rang/list支持默认分区,hash分区不支持。

语法:

CREATE TABLE table_namePARTITION OF parent_table
FOR VALUES DEFAULT

ATTACH/DETACH分区

语法:

ALTER TABLE name     ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT }  ALTER TABLE name    DETACH PARTITION partition_name

示例

create table test_hash(id int, date date)   partition by hash(id);
create table test_hash_1 partition of test_hash   for values with(modulus 2, remainder 0);
create table test_hash_2 partition of test_hash   for values with(modulus 2, remainder 1);
postgres=# \d+ test_hashPartitioned table "public.test_hash"Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------id     | integer |           |          |         | plain   |              | date   | date    |           |          |         | plain   |              |
Partition key: HASH (id)
Partitions: test_hash_1 FOR VALUES WITH (modulus 2, remainder 0),test_hash_2 FOR VALUES WITH (modulus 2, remainder 1)postgres=# alter table test_hash detach partition test_hash_2;
ALTER TABLE
postgres=# \d+ test_hashPartitioned table "public.test_hash"Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------id     | integer |           |          |         | plain   |              | date   | date    |           |          |         | plain   |              |
Partition key: HASH (id)
Partitions: test_hash_1 FOR VALUES WITH (modulus 2, remainder 0)postgres=# create table test_hash_attach (id int, date date);
CREATE TABLE
postgres=# alter table test_hash attach partition test_hash_attach   for values with (modulus 2, remainder 1);
ALTER TABLE
postgres=# \d+ test_hashPartitioned table "public.test_hash"Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------id     | integer |           |          |         | plain   |              | date   | date    |           |          |         | plain   |              |
Partition key: HASH (id)
Partitions: test_hash_1 FOR VALUES WITH (modulus 2, remainder 0),test_hash_attach FOR VALUES WITH (modulus 2, remainder 1)

分区管理

删除分区

直接删除对应的分区表

drop table tbl_partition_202110;

另一个方法就是先将分区表移除,但是保留访问权限

alter table tbl_partition_202110 no inherit tbl_partition;

和直接DROP相比,该方式仅仅是使子表脱离了原有的主表,而存储在子表中的数据仍然可以访问,因为此时该表已经被还原成一个普通的数据表。在这时就可以对该表进行必要的维护操作。如数据清理、归档等。然后可以考虑是直接删除该表,还是先清空该表,然后再重新继承主表。

alter table tbl_partition_202110 inher tbl_partition;

增加分区

1、可以通过新建分区表来增加一个分区

2、可以直接让普通表绑定主表,从而达到新增分区的目的

PostgreSQL中的分区表相关推荐

  1. PostgreSQL中的分区表(创建分区)–第1部分

    PostgreSQL中的分区表很容易做到,它涉及PostgreSQL的继承概念和触发器. 在这里,我提供了一个示例来演示如何在PostgreSQL中对表进行分区. 在继续之前,请了解一些基本概念,例如 ...

  2. Postgresql杂谈 10—Postgresql中的分区表

    一.关于分区表 表分区是在大数据优化中的一种常见的分表方案,通过将大数据按照一定的规则(最常见的是按照时间)进行分表处理,将逻辑上的一个大表分割成物理上的几块表,插入数据时,数据会自动插入到不同的分区 ...

  3. PostgreSQL 中的系统字段:tableoid、xmin、xmax、cmin、cmax、ctid

    文章目录 tableoid ctid xmin xmax cmin cmax oid 总结 大家好!我是只谈技术不剪发的 Tony 老师.今天我们来谈谈 PostgreSQL 数据表中几个隐藏的系统字 ...

  4. postgresql 自动创建分区表

    PostgreSQL中通过继承,可以支持基本的表分区功能,比如按时间,每月创建一个表分区,数据记录到对应分区中.按照官方文档的操作,创建子表和index.修改trigger等工作都必须DBA定期去手动 ...

  5. postgresql中COPY的用法

    一.测试创建表: [postgres@cacti ~]$ cat test.sql CREATE TABLE weather ( city varchar(80), temp_lo int, temp ...

  6. PostgreSQL中的数据库实例、模式、用户(角色)、表空间

    2019独角兽企业重金招聘Python工程师标准>>> 本文参考:http://blog.csdn.net/kanon_lgt/article/details/5931522 htt ...

  7. 插入,在PostgreSQL中重复更新吗?

    本文翻译自:Insert, on duplicate update in PostgreSQL? Several months ago I learned from an answer on Stac ...

  8. PostgreSQL 中的引号与大小写

    单双引号 单引号用来标识实际的值,双引号用来标识表名(table name)或列名(column name)等数据库中存在的值. select "name" from " ...

  9. SQL Server 2005中的分区表

    SQL Server 2005中的分区表(一):什么是分区表?为什么要用分区表?如何创建分区表? SQL Server 2005中的分区表(二):如何添加.查询.修改分区表中的数据 SQL Serve ...

最新文章

  1. 深度学习以及卷积基础
  2. 哈尔滨机器人餐厅打造现实版“未来世界”
  3. pyqt5切换python版本_PyQt5每天必学之切换按钮_python
  4. 连接池Connection Pool 单例设计
  5. Codeforces Round #723 (Div. 2) D. Kill Anton 线段树 + 暴力
  6. Android官方开发文档Training系列课程中文版:与其它APP交互之从Activity获得结果
  7. mysql linux导入csv主键,MySQL导入csv文件内容到Table及数据库的自增主键设置
  8. C#设计模式之16-迭代器模式
  9. android布局添加背景颜色,android-获取布局的背景色
  10. 60-40-040-序列化-Twitter 的Avro序列化
  11. Python补充之函数
  12. Docker系列(二)Docker安装与启动
  13. html表白树代码程序怎么调,抖音表白弹窗vbs代码怎么制作 表白树特效程序代码教程详细介绍...
  14. 小爱同学音色定制服务器响应失败,小爱同学自定义音色
  15. 使用go进行人脸识别活体检测
  16. 各种LOGO设计标准尺寸
  17. 计算机需要权限来执行此操作 win7,win7系统删除提示“文件夹访问被拒绝,需要权限执行此操作”怎么办...
  18. xcode打包mac桌面程序
  19. [工业互联-1]:工业互联全局概述
  20. C++GUI之wxWidgets(1)-安装与测试

热门文章

  1. java七武器系列_Java七武器系列孔雀翎-- 问题诊断神器BTrace
  2. JS本地存储(附实例)
  3. HTTP 响应状态码
  4. 映像劫持,windows服务启动的两种形式
  5. Centos7安装watchman编译不通过
  6. 做新时代弄潮儿!文创产业智能化的融合与颠覆
  7. mysql全文检索优化_mysql全文检索 实现搜索优化
  8. 基于ASP.NET+SQL Server的网站登录注册功能设计与实现【100010308】
  9. Java实现mds降维_ISOMAP和MDS降维
  10. X86汇编——标志寄存器