溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PostgreSQL12.5中分區(qū)表的操作方法有哪些

發(fā)布時間:2022-08-12 14:08:17 來源:億速云 閱讀:243 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“PostgreSQL12.5中分區(qū)表的操作方法有哪些”,在日常操作中,相信很多人在PostgreSQL12.5中分區(qū)表的操作方法有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PostgreSQL12.5中分區(qū)表的操作方法有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

    1、創(chuàng)建一個有DEFAULT的分區(qū)表

    1、先創(chuàng)建主表

    create table tbl_log
    (
        id          serial,
        create_time timestamp(0) without time zone,
        remark      char(1)
    ) PARTITION BY RANGE (create_time);
    #因為是serial類型,自增的所以會自動創(chuàng)建一個序列
    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、如果沒有創(chuàng)建分區(qū)就直接插入數(shù)據(jù)會報錯

    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、創(chuàng)建分區(qū)

    #包括左邊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、查看分區(qū)情況

    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 分區(qū),再加分區(qū)

    因為有default 分區(qū),再加分區(qū),所以會報錯

    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

    解決辦法:

    以上添加分區(qū)報錯,需要解綁default分區(qū),之后再添加,如下

    1、解綁Default分區(qū)

    postgres=# ALTER TABLE tbl_log DETACH PARTITION tbl_log_default;
    ALTER TABLE

    2、創(chuàng)建想要的分區(qū)

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

    3、分區(qū)創(chuàng)建成功,分區(qū)創(chuàng)建之后需把DEFAULT分區(qū)連接。

    連接DEFAULT分區(qū)報錯,如下:

    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分區(qū)內(nèi)有2018-04-01的數(shù)據(jù),把這個數(shù)據(jù)從tbl_log_default中導(dǎo)出到對應(yīng)的分區(qū),并清理tbl_log_default中的對應(yīng)的數(shù)據(jù)

    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分區(qū)成功

    postgres=# ALTER TABLE tbl_log ATTACH PARTITION tbl_log_default DEFAULT;
    ALTER TABLE

    3、沒有default的分區(qū)

    創(chuàng)建沒有default的分區(qū),當插入的數(shù)據(jù)超過規(guī)劃好的分區(qū)的時候會報錯

    1、創(chuàng)建1月份分區(qū)

    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月的數(shù)據(jù)就會報錯

    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、給分區(qū)表ddl

    4.1、在原來沒有主鍵的分區(qū)表加主鍵

    結(jié)論:

    1、在主表加主鍵,主鍵為僅僅想要的主鍵,會報錯,需要用想要的主鍵+分區(qū)鍵組合為主鍵

    2、分區(qū)表可以單獨添加主鍵

    1.1、在主表加主鍵,主鍵為僅僅想要的主鍵,報錯如下 must include all partitioning columns

    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、在主表添加主鍵需要是想要的主鍵+分區(qū)鍵

    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、可以給分區(qū)表單獨添加主鍵

    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、創(chuàng)建分區(qū)表時,就指定主鍵

    主鍵不包括分區(qū)鍵,報錯提示must include all partitioning columns

    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.

    修改語句,添加分區(qū)鍵也為主鍵,創(chuàng)建成功

    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、分區(qū)表加字段,修改字段

    1、加字段,可以成功添加,在主表加字段,分區(qū)表會自動添加

    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、直接在分區(qū)表加字段會報錯

    postgres=# alter table tbl_log_p201801 add name2 varchar(2);
    ERROR:  cannot add column to a partition

    3、修改字段

    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=#

    到此,關(guān)于“PostgreSQL12.5中分區(qū)表的操作方法有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI