PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да мигрираме съществуваща Postgres таблица към разделена таблица възможно най-прозрачно?

В Postgres 10 беше въведено „Декларативно разделяне“, което може да ви освободи от голяма част от работа, като генериране на тригери или правила с огромни оператори if/else, пренасочващи към правилната таблица. Postgres може да направи това автоматично сега. Да започнем с миграцията:

  1. Преименувайте старата таблица и създайте нова разделена таблица

    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);
    

Това едва ли трябва да изисква обяснение. Старата таблица се преименува (след миграцията на данни ще я изтрием) и получаваме главна таблица за нашия дял, която по същество е същата като оригиналната ни таблица, но без индекси)

  1. Създайте функция, която може да генерира нови дялове, както са ни необходими:

    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;
    

Това ще ви бъде полезно по-късно.

  1. Създайте изглед, който просто делегира на нашата главна таблица:

    create or replace view myTable as select * from myTable_master;
    
  2. Създайте правило, така че когато вмъкнем в правилото, не само ще актуализираме разделената таблица, но и ще създадем нов дял, ако е необходимо:

    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)
        );
    

Разбира се, ако имате нужда и от update и delete , имате нужда и от правило за тези, които трябва да са прави.

  1. Всъщност мигрирайте старата таблица:

    -- 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;
    

Сега миграцията на таблицата е завършена, без да е имало нужда да се знае колко дяла са необходими, както и изгледът myTable ще бъде абсолютно прозрачен. Можете лесно да вмъквате и избирате от тази таблица, както преди, но може да получите полза от производителността от разделянето.

Имайте предвид, че изгледът е необходим само, тъй като разделена таблица не може да има задействания на редове. Ако можете да се разберете с извикването на createPartitionIfNotExists ръчно, когато е необходимо от вашия код, нямате нужда от изгледа и всички негови правила. В този случай трябва да добавите дяловете ръчно по време на миграция:

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. Клаузи за грижа:Всичко за SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY и LIMIT

  2. 7 неща, за които трябва да внимавате при внедряването на PostgreSQL

  3. Проверете дали JSON масивът на Postgres съдържа низ

  4. Как да използвам повторно резултат за клаузите SELECT, WHERE и ORDER BY?

  5. Как да импортирате CSV файл в PostgreSQL