广告位联系
返回顶部
分享到

PostgreSQL12.5中分区表的一些操作介绍

PostgreSQL 来源:互联网 作者:F11站长开发者 发布时间:2022-08-12 15:34:48 人浏览
摘要

1、创建一个有DEFAULT的分区表 1、先创建主表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 create table tbl_log ( id serial, create_time timestamp(0) without time zone, remark char(1) ) PARTITION BY RANGE (create_time); #因为是serial类型

1、创建一个有DEFAULT的分区表

1、先创建主表

1

2

3

4

5

6

7

8

9

10

11

12

13

14

create table tbl_log

(

    id          serial,

    create_time timestamp(0) without time zone,

    remark      char(1)

) PARTITION BY RANGE (create_time);

#因为是serial类型,自增的所以会自动创建一个序列

postgres=# \d

                   List of relations

 Schema |      Name      |       Type        |  Owner  

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

 public | tbl_log        | partitioned table | postgres

 public | tbl_log_id_seq | sequence          | postgres

(7 rows)

2、如果没有创建分区就直接插入数据会报错

1

2

3

4

postgres=# INSERT INTO tbl_log(id, create_time, remark) VALUES (1, '2018-02-01', 'a');

ERROR:  no partition of relation "tbl_log" found for row

DETAIL:  Partition key of the failing row contains (create_time) = (2018-02-01 00:00:00).

postgres=#

3、创建分区

1

2

3

4

5

6

7

8

9

#包括左边1.1,不包括2.1

CREATE TABLE tbl_log_p201801 PARTITION OF tbl_log FOR VALUES FROM ('2018-01-01') TO ('2018-02-01');

CREATE TABLE tbl_log_p201802 PARTITION OF tbl_log FOR VALUES FROM ('2018-02-01') TO ('2018-03-01');

CREATE TABLE tbl_log_p201803 PARTITION OF tbl_log FOR VALUES FROM ('2018-03-01') TO ('2018-04-01');

CREATE TABLE tbl_log_default PARTITION OF tbl_log DEFAULT;

INSERT INTO tbl_log(id, create_time, remark) VALUES (1, '2018-02-01', 'a');

INSERT INTO tbl_log(id, create_time, remark) VALUES (2, '2018-03-01', 'b');

INSERT INTO tbl_log(id, create_time, remark) VALUES (3, '2018-04-01', 'd');

INSERT INTO tbl_log(id, create_time, remark) VALUES (4, '2020-07-01', 'c');

4、查看分区情况

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

postgres=# select * from tbl_log;

 id |     create_time     | remark

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

  1 | 2018-02-01 00:00:00 | a

  2 | 2018-03-01 00:00:00 | b

  3 | 2018-04-01 00:00:00 | d

  4 | 2020-07-01 00:00:00 | c

(4 rows)

postgres=# select * from tbl_log_p201801;

 id | create_time | remark

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

(0 rows)

postgres=# select * from tbl_log_p201802;

 id |     create_time     | remark

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

  1 | 2018-02-01 00:00:00 | a

(1 row)

postgres=# select * from tbl_log_p201803;

 id |     create_time     | remark

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

  2 | 2018-03-01 00:00:00 | b

(1 row)

                       

postgres=# select * from tbl_log_default;

 id |     create_time     | remark

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

  3 | 2018-04-01 00:00:00 | d

  4 | 2020-07-01 00:00:00 | c

(2 rows)

postgres=#

2、有default 分区,再加分区

因为有default 分区,再加分区,所以会报错

1

2

postgres=# CREATE TABLE tbl_log_p201804 PARTITION OF tbl_log FOR VALUES FROM ('2018-04-01') TO ('2018-05-01');

ERROR:  updated partition constraint for default partition "tbl_log_default" would be violated by some row

解决办法:

以上添加分区报错,需要解绑default分区,之后再添加,如下

1、解绑Default分区

1

2

postgres=# ALTER TABLE tbl_log DETACH PARTITION tbl_log_default;

ALTER TABLE

2、创建想要的分区

1

2

postgres=# CREATE TABLE tbl_log_p201804 PARTITION OF tbl_log FOR VALUES FROM ('2018-04-01') TO ('2018-05-01');

CREATE TABLE

3、分区创建成功,分区创建之后需把DEFAULT分区连接。

连接DEFAULT分区报错,如下:

1

2

3

4

5

postgres=# ALTER TABLE tbl_log ATTACH PARTITION tbl_log_default DEFAULT;

ERROR:  partition constraint is violated by some row

postgres=# INSERT INTO tbl_log_p201804 SELECT * FROM tbl_log_default;

ERROR:  new row for relation "tbl_log_p201804" violates partition constraint

DETAIL:  Failing row contains (4, 2020-07-01 00:00:00, c).

因为tbl_log_default分区内有2018-04-01的数据,把这个数据从tbl_log_default中导出到对应的分区,并清理tbl_log_default中的对应的数据

1

2

3

4

postgres=# INSERT INTO tbl_log_p201804 SELECT * FROM tbl_log_default where create_time>='2018-04-01' and create_time<'2018-05-01';

INSERT 0 1

postgres=# delete from tbl_log_default where create_time>='2018-04-01' and create_time<'2018-05-01';

DELETE 1

4、再次连接DEFAULT分区成功

1

2

postgres=# ALTER TABLE tbl_log ATTACH PARTITION tbl_log_default DEFAULT;

ALTER TABLE

3、没有default的分区

创建没有default的分区,当插入的数据超过规划好的分区的时候会报错

1、创建1月份分区

1

2

3

4

5

6

7

create table tbl_log2

(

    id          serial,

    create_time timestamp(0) without time zone,

    remark      char(1)

) PARTITION BY RANGE (create_time);

CREATE TABLE tbl_log2_p201801 PARTITION OF tbl_log2 FOR VALUES FROM ('2018-01-01') TO ('2018-02-01');

插入2月的数据就会报错

1

2

3

4

5

postgres=# INSERT INTO tbl_log2(id, create_time, remark) VALUES (1, '2018-01-01', 'a');

INSERT 0 1

postgres=# INSERT INTO tbl_log2(id, create_time, remark) VALUES (1, '2018-02-01', 'a');

ERROR:  no partition of relation "tbl_log2" found for row

DETAIL:  Partition key of the failing row contains (create_time) = (2018-02-01 00:00:00).

4、给分区表ddl

4.1、在原来没有主键的分区表加主键

结论:

1、在主表加主键,主键为仅仅想要的主键,会报错,需要用想要的主键+分区键组合为主键

2、分区表可以单独添加主键

1.1、在主表加主键,主键为仅仅想要的主键,报错如下 must include all partitioning columns

1

2

3

4

postgres=# alter table tbl_log add primary key(id);

ERROR:  unique constraint on partitioned table must include all partitioning columns

DETAIL:  PRIMARY KEY constraint on table "tbl_log" lacks column "create_time" which is part of the partition key.

postgres=# alter table tbl_log add primary key(id)

1.2、在主表添加主键需要是想要的主键+分区键

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

postgres=# alter table tbl_log add primary key (id,create_time);

ALTER TABLE

postgres=# \d tbl_log

                                    Partitioned table "public.tbl_log"

   Column    |              Type              | Collation | Nullable |               Default              

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

 id          | integer                        |           | not null | nextval('tbl_log_id_seq'::regclass)

 create_time | timestamp(0) without time zone |           | not null |

 remark      | character(1)                   |           |          |

 name        | character varying(2)           |           |          |

Partition key: RANGE (create_time)

Indexes:

    "tbl_log_pkey" PRIMARY KEY, btree (id, create_time)

Number of partitions: 5 (Use \d+ to list them.)

postgres=# \d tbl_log_p201801

                                      Table "public.tbl_log_p201801"

   Column    |              Type              | Collation | Nullable |               Default              

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

 id          | integer                        |           | not null | nextval('tbl_log_id_seq'::regclass)

 create_time | timestamp(0) without time zone |           | not null |

 remark      | character(1)                   |           |          |

 name        | character varying(2)           |           |          |

Partition of: tbl_log FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2018-02-01 00:00:00')

Indexes:

    "tbl_log_p201801_pkey" PRIMARY KEY, btree (id, create_time)

1.3、可以给分区表单独添加主键

1

2

3

4

5

6

7

8

9

10

11

12

13

14

postgres=# alter table tbl_log_p201801 add primary key (id);

ALTER TABLE

postgres=# \d tbl_log_p201801

                                      Table "public.tbl_log_p201801"

   Column    |              Type              | Collation | Nullable |               Default              

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

 id          | integer                        |           | not null | nextval('tbl_log_id_seq'::regclass)

 create_time | timestamp(0) without time zone |           |          |

 remark      | character(1)                   |           |          |

 name        | character varying(2)           |           |          |

Partition of: tbl_log FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2018-02-01 00:00:00')

Indexes:

    "tbl_log_p201801_pkey" PRIMARY KEY, btree (id)

postgres=#

4.2、创建分区表时,就指定主键

主键不包括分区键,报错提示must include all partitioning columns

1

2

3

4

5

6

7

8

9

create table tbl_log2

(

    id          int,

    create_time timestamp(0) without time zone,

    remark      char(1),

    primary key (id)

);

ERROR:  unique constraint on partitioned table must include all partitioning columns

DETAIL:  PRIMARY KEY constraint on table "tbl_log2" lacks column "create_time" which is part of the partition key.

修改语句,添加分区键也为主键,创建成功

1

2

3

4

5

6

7

8

create table tbl_log2

(

    id          int,

    create_time timestamp(0) without time zone,

    remark      char(1),

    primary key (id,create_time)

) PARTITION BY RANGE (create_time);

CREATE TABLE

4.3、分区表加字段,修改字段

1、加字段,可以成功添加,在主表加字段,分区表会自动添加

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

postgres=# alter table tbl_log add name varchar(2);

ALTER TABLE

postgres=# \d tbl_log;

                                    Partitioned table "public.tbl_log"

   Column    |              Type              | Collation | Nullable |               Default              

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

 id          | integer                        |           | not null | nextval('tbl_log_id_seq'::regclass)

 create_time | timestamp(0) without time zone |           |          |

 remark      | character(1)                   |           |          |

 name        | character varying(2)           |           |          |

Partition key: RANGE (create_time)

Number of partitions: 5 (Use \d+ to list them.)

postgres=# \d tbl_log_p201801;                    

                                      Table "public.tbl_log_p201801"

   Column    |              Type              | Collation | Nullable |               Default              

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

 id          | integer                        |           | not null | nextval('tbl_log_id_seq'::regclass)

 create_time | timestamp(0) without time zone |           |          |

 remark      | character(1)                   |           |          |

 name        | character varying(2)           |           |          |

Partition of: tbl_log FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2018-02-01 00:00:00')

2、直接在分区表加字段会报错

1

2

postgres=# alter table tbl_log_p201801 add name2 varchar(2);

ERROR:  cannot add column to a partition

3、修改字段

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

postgres=# alter table tbl_log  alter column remark type varchar(10);

ALTER TABLE

postgres=# \d tbl_log;

                                    Partitioned table "public.tbl_log"

   Column    |              Type              | Collation | Nullable |               Default              

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

 id          | integer                        |           | not null | nextval('tbl_log_id_seq'::regclass)

 create_time | timestamp(0) without time zone |           | not null |

 remark      | character varying(10)          |           |          |

 name        | character varying(2)           |           |          |

Partition key: RANGE (create_time)

Indexes:

    "tbl_log_pkey" PRIMARY KEY, btree (id, create_time)

Number of partitions: 5 (Use \d+ to list them.)

postgres=# \d tbl_log_p201801

                                      Table "public.tbl_log_p201801"

   Column    |              Type              | Collation | Nullable |               Default              

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

 id          | integer                        |           | not null | nextval('tbl_log_id_seq'::regclass)

 create_time | timestamp(0) without time zone |           | not null |

 remark      | character varying(10)          |           |          |

 name        | character varying(2)           |           |          |

Partition of: tbl_log FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2018-02-01 00:00:00')

Indexes:

    "tbl_log_p201801_pkey" PRIMARY KEY, btree (id, create_time)

postgres=#


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 : https://blog.csdn.net/weixin_42583514/article/details/123063420
    Tag :
相关文章
  • Postgresql删除数据库表中重复数据的几种方法
    一直使用Postgresql数据库,有一张表是这样的: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 DROP TABLE IF EXISTS public.devicedata; CREATE TABLE public.devicedata ( Id varchar(20
  • PostgreSQL HOT与PHOT有哪些区别

    PostgreSQL HOT与PHOT有哪些区别
    1、HOT概述 PostgreSQL中,由于其多版本的特性,当我们进行数据更新时,实际上并不是直接修改元数据,而是通过新插入一行数据来进行间接
  • PostgreSQL索引失效会发生什么?

    PostgreSQL索引失效会发生什么?
    前段时间碰到个奇怪的索引失效的问题,实际情况类似下面这样: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 bill=# begin; BEGIN bill=*# create inde
  • PostgreSQL pg_filenode.map文件介绍

    PostgreSQL pg_filenode.map文件介绍
    今天在网上看到有人问误删pg_filenode.map该如何恢复或者重建,解决这个问题前我们先来了解下pg_filenode.map文件。 对于PostgreSQL中的每张表在磁
  • PostgreSQL limit的神奇作用介绍
    最近碰到这样一个SQL引发的性能问题,SQL内容大致如下: 1 2 3 4 5 6 7 SELECT * FROM t1 WHERE id = 999 AND (case $1 WHEN true THEN info = $2 ELSE info = $3 end) l
  • PostgreSql生产级别数据库安装要注意事项

    PostgreSql生产级别数据库安装要注意事项
    我让公司的小伙伴写一个生产级别的PostgreSQL的安装文档,结果他和我说:不是用一个命令就能安装好么?还用写文档么?。我知道他想说的
  • PostgreSQL12.5中分区表的一些操作介绍
    1、创建一个有DEFAULT的分区表 1、先创建主表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 create table tbl_log ( id serial, create_time timestamp(0) without time zone, remark char
  • Postgres中UPDATE更新语句源码分析
    PG中UPDATE源码分析 本文主要描述SQL中UPDATE语句的源码分析,代码为PG13.3版本。 整体流程分析 以update dtea set id = 1;这条最简单的Update语句进行
  • 在Centos8-stream安装PostgreSQL13的教程

    在Centos8-stream安装PostgreSQL13的教程
    一、安装postgresql13-server 1 2 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install -y postgresql13-
  • PostgreSQL自动更新时间戳实例介绍
    什么是PostgreSQL时间戳数据类型? 在PostgreSQL中,下一个数据类型是 TIMESTAMP ,它可以存储 TIME 和 DATE 值。但它不支持任何 时区数据。这意味
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计