暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

【磐维数据库】分区表之二级分区

Darcy 2024-06-01
512

一. 功能描述

二级分区功能,即在原有的range分区、list分区、hash分区、interval分区的基础上再次进行分区。

二级分区可以对表中的每个分区再次进行分区。分区类型有range、list、hash三种,一级与二级分区的分区类型可以任意组合。二级分区支持使用CREATE/ALTER/SELECT语法,用于二级分区的创建与增删改查。二级分区的相关信息可在系统表PG_PARTITION中获取。

PG_PARTITION系统表存储数据库内所有分区表(partitioned table)、分区(table partition)、分区上toast表和分区索引(index partition)四类对象的信息。分区表索引(partitioned index)的信息不在PG_PARTITION系统表中保存。

表 1 PG_PARTITION字段

名称

类型

描述

oid

oid

行标识符(隐含属性,必须明确选择)。

relname

name

分区表、分区、分区上toast表和分区索引的名称。

parttype

"char"

对象类型:

'r':partitioned table。

'p':table partition。

's':table subpartition。

'x':index partition。

't':toast table。

parentid

oid

当对象为分区表或分区时,此字段表示分区表在PG_CLASS中的OID。

当对象为index partition时,此字段表示所属分区表索引(partitioned index)的OID。

partitionid

oid

分区表的分区号。

rangenum

integer

保留字段。

intervalnum

integer

保留字段。

partstrategy

"char"

分区表分区策略,现在仅支持:

'r':范围分区。

'v':数值分区。

'i':间隔分区。

'l':list分区。

'h':hash分区。

'n':无效分区。

subpartstrategy

"char"

子分区策略。

relfilenode

oid

table partition、index partition、分区上toast表的物理存储位置。

reltablespace

oid

table partition、index partition、分区上toast表所属表空间的OID。

relpages

double precision

统计信息:table partition、index partition的数据页数量。

reltuples

double precision

统计信息:table partition、index partition的元组数。

relallvisible

integer

统计信息:table partition、index partition的可见数据页数。

reltoastrelid

oid

table partition所对应toast表的OID。

reltoastidxid

oid

table partition所对应toast表的索引的OID。

indextblid

oid

index partition对应table partition的OID。

indisusable

boolean

分区索引是否可用。

reldeltarelid

oid

Delta表的OID。

reldeltaidx

oid

Delta表的索引表的OID。

relcudescrelid

oid

CU描述表的OID。

relcudescidx

oid

CU描述表的索引表的OID。

relfrozenxid

xid32

冻结事务ID号。

为保持前向兼容,保留此字段,新增relfrozenxid64用于记录此信息。

intspnum

integer

间隔分区所属表空间的个数。

partkey

int2vector

分区键的列号。

intervaltablespace

oidvector

间隔分区所属的表空间,间隔分区以round-robin方式落在这些表空间内。

interval

text[]

间隔分区的间隔值。

boundaries

text[]

范围分区和间隔分区的上边界。

transit

text[]

间隔分区的跳转点。

reloptions

text[]

设置partition的存储属性,与pg_class.reloptions的形态一样,用“keyword=value”格式的字符串来表示,目前用于在线扩容的信息搜集。

relfrozenxid64

xid

冻结事务ID号。

relminmxid

xid

冻结多事务ID号。

subpartkey

int2vector

子分区键的列号。

subparttemplate

pg_node_tree

临时子分区,可以避免增加分区时建在默认表空间。

relfrozenxid64

xid

(”frozen”)事务ID替换。该字段用于跟踪此表是否需要为了防止事务ID重叠(或者允许收缩pg_clog)而进行清理。如果该关系不是表则为零(InvalidTransactionId)。

relminmxid

xid

该表中所有在这个之前的多事务ID已经被一个事务ID替换。这用于跟踪该表是否需要为了防止多事务ID重叠或者允许收缩pg_clog而进行清理。如果该关系不是表则为零(InvalidTransactionId)。

二. 注意事项

interval分区不能作为二级分区。

三. 语法格式

创建、修改和删除二级分区的语法格式请参考:CREATE TABLE SUBPARTITION、ALTER TABLE SUBPARTITION。用户也可以使用如下命令在gsql客户端中查询相关SQL语法的使用帮助信息。

\h create table subpartition

\h alter table subpartition

说明:二级分区的增删改查:对二级分区表插入数据的语法与普通表的语法没有任何差别。当向二级分区表插入数据时,会根据一级分区和二级分区规则,把数据分布到匹配的二级分区中进行存储。

以下列举了部分与二级分区相关的常用SQL句式。

  • 新增一级与二级分区:
  • ALTER TABLE table_name ADD partition_desc [ ( subpartition_desc [, ... ] ) ]
  • 删除指定一级分区包括属于它的所有二级分区:
  • ALTER TABLE table_name DROP PARTITION { partition_name | { FOR ( value [ , … ] ) }
  • 为指定一级分区新增二级分区:
  • ALTER TABLE table_name MODIFY PARTITION partition_name ADD subpartition_desc
  • 删除指定二级分区:
  • ALTER TABLE table_name DROP SUBPARTITION { subpartition_name | { FOR ( value [ , … ] ) }
  • 删除数据:
  • DELETE FROM table_name [ PARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] [ WHERE ...]
    DELETE FROM table_name [ SUBPARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] [ WHERE ...]
  • 更新数据:
  • UPDATE table_name [ PARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] SET [ WHERE ...]
    UPDATE table_name [ SUBPARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] SET [ WHERE ...]
  • 在指定二级分区查找数据:
  • SELECT ... FROM table_name SUBPARTITION (subpartition_name)
  • 单独查询某个分区或子分区数据:
  • SELECT ... FROM table_name PARTITION { ( partition_name ) | FOR ( value [ , ... ] ) }
    SELECT ... FROM table_name SUBPARTITION { ( subpartition_name ) | {FOR ( value [, … ] ) }
  • 当查询二级分区表的数据时(不能指定分区或子分区),如果查询条件中包含有分区键的条件,则在生成执行计划时会根据分区键条件过滤掉不符合条件的分区或子分区:
  • EXPLAIN SELECT ... FROM table_name WHERE ...

四. 参数说明

  • table_name

表名。

  • partition_name

分区表的名称。

  • subpartition_name

二级分区表的名称。

  • SUBPARTITION BY [RANGE | LIST | HASH ]

根据column_name指定的字段进行二级分区,分区类型可以是RANGE、LIST、 HASH其一。

  • SUBPARTITION TEMPLATE ( subpartition_desc [, … ])

常规子分区模板定义语法,适用于Range/List/Hash子分区,当分区定义中没有指定子分区的定义时会根据子分区模板自动生成二级分区。

若没有提供子分区模板,同时partition_desc也不指定subpartition_desc,则将创建一个默认子分区。

  • hash_subpartition_by_quantity

Hash分区持有的子分区模板定义语法(也可用与子分区定义语法),指定创建N个Hash子分区,同时可选指定Hash子分区的tablespace名列表。

五. 示例

示例1

二级分区的创建,修改和删除。

1、创建一个分区表并插入数据。

create table t_part_list_range

( id number not null,

partition_key int,

subpartition_key int,

col2 varchar2(10)

)

partition by list(partition_key)

subpartition by range(subpartition_key)

(

partition t_partition_01 values (100)

(subpartition sub_1_1 values less than (10),

subpartition sub_1_2 values less than (20)

),

partition t_partition_02 values (200)

(subpartition sub_2_1 values less than (10),

subpartition sub_2_2 values less than (20)

)

);

insert into t_part_list_range values(1,100,5,'sub_1_1');

insert into t_part_list_range values(2,100,15,'sub_1_2');

insert into t_part_list_range values(3,200,5,'sub_2_1');

insert into t_part_list_range values(4,200,15,'sub_2_2');

insert into t_part_list_range values(5,200,16,'sub_2_2');

select * from t_part_list_range subpartition for (100,5);

2、新增一级与二级分区。

alter table t_part_list_range add partition t_partition_03 values (300)

( subpartition sub_3_1 values less than (10),

subpartition sub_3_2 values less than (20)

);

3、删除指定一级分区包括属于它的所有二级分区。

alter table t_part_list_range drop partition t_partition_02;

4、为指定一级分区新增二级分区。

alter table t_part_list_range modify partition t_partition_01 add subpartition sub_1_3 values less than (30);

5、删除指定二级分区。

alter table t_part_list_range drop subpartition sub_1_3;

示例2

一级分区为interval分区,二级分区为list分区,分区键类型为字符类型;创建并查看分区结果。

1、创建测试表,包含一级分区和二级分区。

CREATE TABLE t_subpartition_interval_list(

partition_key date,

subpartition_key varchar(20),

test varchar(20)

)partition by range(partition_key)

interval('12 month')

subpartition by list(subpartition_key)

(partition partition_p1 VALUES LESS THAN ('2019-01-01')

(subpartition sub_1_1 values('test1'),

subpartition sub_1_2 values('test2'),

subpartition sub_1_3 values (default)

),

partition partition_p2 VALUES LESS THAN ('2021-01-01')

(subpartition sub_2_1 values('test1'),

subpartition sub_2_2 values('test2'),

subpartition sub_2_3 values (default)

)

);

2、插入测试数据。

INSERT INTO t_subpartition_interval_list VALUES('2018-09-02','test','test1');

INSERT INTO t_subpartition_interval_list VALUES('2020-12-12','test2','test2');

INSERT INTO t_subpartition_interval_list VALUES('2022-02-02','interval','test3');

3、查询已有分区对应数据。

select * from t_subpartition_interval_list subpartition(sub_1_3);

select * from t_subpartition_interval_list subpartition(sub_2_2);

返回结果为:

partition_key | subpartition_key | test

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

2018-09-02 00:00:00 | test | test1

(1 row)

partition_key | subpartition_key | test

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

2020-12-12 00:00:00 | test2 | test2

(1 row)

4、查询表新增分区名。

select relname,parttype,partstrategy,boundaries

from pg_partition

where parentid = (select oid from pg_class where relname = 't_subpartition_interval_list')

union all

select relname,parttype,partstrategy,boundaries from pg_partition

where parentid in (

select oid from pg_partition

where parentid = (

select oid from pg_class where relname ='t_subpartition_interval_list'

)

order by relname)

order by relname;

返回结果为:

relname | parttype | partstrategy | boundaries

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

partition_p1 | p | r | {2019-01-01}

partition_p2 | p | r | {2021-01-01}

sub_1_1 | s | l | {test1}

sub_1_2 | s | l | {test2}

sub_1_3 | s | l |

sub_2_1 | s | l | {test1}

sub_2_2 | s | l | {test2}

sub_2_3 | s | l |

sys_p1 | p | i | {"2023-01-01 00:00:00"}

sys_p1_subpartdefault1 | s | l |

t_subpartition_interval_list | r | i |

(11 rows)

5、查询新增分区对应数据。

select * from t_subpartition_interval_list subpartition(sys_p1_subpartdefault1);

返回结果为:

partition_key | subpartition_key | test

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

2022-02-02 00:00:00 | interval | test3

(1 row)

最后修改时间:2025-09-30 00:43:25
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论