PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm cách nào để di chuyển Bảng Postgres hiện có sang bảng được phân vùng một cách minh bạch nhất có thể?

Trong Postgres 10, "Phân vùng khai báo" đã được giới thiệu, có thể giúp bạn giải quyết rất nhiều công việc như tạo trình kích hoạt hoặc quy tắc với các câu lệnh if / else khổng lồ chuyển hướng đến bảng chính xác. Postgres có thể tự động làm việc này ngay bây giờ. Hãy bắt đầu với việc di chuyển:

  1. Đổi tên bảng cũ và tạo một bảng được phân vùng mới

    alter table myTable rename to myTable_old;
    
    create table myTable_master(
        forDate date not null,
        key2 int not null,
        value int not null
    ) partition by range (forDate);
    

Điều này hầu như không cần bất kỳ lời giải thích nào. Bảng cũ được đổi tên (sau khi di chuyển dữ liệu, chúng tôi sẽ xóa nó) và chúng tôi nhận được một bảng chính cho phân vùng của chúng tôi về cơ bản giống với bảng gốc của chúng tôi, nhưng không có chỉ mục)

  1. Tạo một hàm có thể tạo các phân vùng mới khi chúng ta cần:

    create function createPartitionIfNotExists(forDate date) returns void
    as $body$
    declare monthStart date := date_trunc('month', forDate);
        declare monthEndExclusive date := monthStart + interval '1 month';
        -- We infer the name of the table from the date that it should contain
        -- E.g. a date in June 2005 should be int the table mytable_200506:
        declare tableName text := 'mytable_' || to_char(forDate, 'YYYYmm');
    begin
        -- Check if the table we need for the supplied date exists.
        -- If it does not exist...:
        if to_regclass(tableName) is null then
            -- Generate a new table that acts as a partition for mytable:
            execute format('create table %I partition of myTable_master for values from (%L) to (%L)', tableName, monthStart, monthEndExclusive);
            -- Unfortunatelly Postgres forces us to define index for each table individually:
            execute format('create unique index on %I (forDate, key2)', tableName);
        end if;
    end;
    $body$ language plpgsql;
    

Điều này sẽ hữu ích sau này.

  1. Tạo một dạng xem về cơ bản chỉ ủy quyền cho bảng chính của chúng ta:

    create or replace view myTable as select * from myTable_master;
    
  2. Tạo quy tắc để khi chúng tôi chèn vào quy tắc, chúng tôi sẽ không chỉ cập nhật bảng đã phân vùng mà còn tạo một phân vùng mới nếu cần:

    Thay vào đó,
    create or replace rule autoCall_createPartitionIfNotExists as on insert
        to myTable
        do instead (
            select createPartitionIfNotExists(NEW.forDate);
            insert into myTable_master (forDate, key2, value) values (NEW.forDate, NEW.key2, NEW.value)
        );
    

Tất nhiên, nếu bạn cũng cần updatedelete , bạn cũng cần một quy tắc cho những quy tắc đó phải được thực hiện ngay.

  1. Trên thực tế, hãy di chuyển bảng cũ:

    -- Finally copy the data to our new partitioned table
    insert into myTable (forDate, key2, value) select * from myTable_old;
    
    -- And get rid of the old table
    drop table myTable_old;
    

Giờ đây, quá trình di chuyển bảng đã hoàn tất mà không cần biết có bao nhiêu phân vùng cần thiết và cả chế độ xem myTable sẽ được minh bạch tuyệt đối. Bạn có thể đơn giản chèn và chọn từ bảng đó như trước đây, nhưng bạn có thể nhận được lợi ích về hiệu suất từ ​​việc phân vùng.

Lưu ý rằng chế độ xem chỉ cần thiết vì một bảng được phân vùng không thể có trình kích hoạt hàng. Nếu bạn có thể hòa nhập với việc gọi createPartitionIfNotExists theo cách thủ công bất cứ khi nào cần từ mã của bạn, bạn không cần chế độ xem và tất cả các quy tắc của nó. Trong trường hợp này, bạn cần phải thêm các phân vùng theo cách thủ công trong quá trình di chuyển:

do
$$
declare rec record;
begin
    -- Loop through all months that exist so far...
    for rec in select distinct date_trunc('month', forDate)::date yearmonth from myTable_old loop
        -- ... and create a partition for them
        perform createPartitionIfNotExists(rec.yearmonth);
    end loop;
end
$$;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sắp xếp chữ và số với PostgreSQL

  2. psql:không thể kết nối với máy chủ:Kết nối bị từ chối Lỗi khi kết nối với cơ sở dữ liệu từ xa

  3. Hàm MIN () trong PostgreSQL

  4. Ánh xạ trường điểm hình học PostGIS với Hibernate trên Spring Boot

  5. Thêm một trong hai ràng buộc không null trong postgresql