Поскольку # 1 требует копирования данных с мастера на дочерний объект, пока он находится в активной производственной среде, я лично пошел с # 2 (создание нового мастера). Это предотвращает сбои в работе исходной таблицы, когда она активно используется, и если есть какие-либо проблемы, я могу легко удалить новый мастер без проблем и продолжить использовать исходную таблицу. Вот шаги, чтобы сделать это:
Создать новую мастер-таблицу.
CREATE TABLE new_master (
id serial,
counter integer,
dt_created DATE DEFAULT CURRENT_DATE NOT NULL
);
Создайте детей, которые наследуют от мастера.
CREATE TABLE child_2014 (
CONSTRAINT pk_2014 PRIMARY KEY (id),
CONSTRAINT ck_2014 CHECK ( dt_created < DATE '2015-01-01' )
) INHERITS (new_master);
CREATE INDEX idx_2014 ON child_2014 (dt_created);
CREATE TABLE child_2015 (
CONSTRAINT pk_2015 PRIMARY KEY (id),
CONSTRAINT ck_2015 CHECK ( dt_created >= DATE '2015-01-01' AND dt_created < DATE '2016-01-01' )
) INHERITS (new_master);
CREATE INDEX idx_2015 ON child_2015 (dt_created);
...
Скопируйте все исторические данные в новую основную таблицу
INSERT INTO child_2014 (id,counter,dt_created)
SELECT id,counter,dt_created
from old_master
where dt_created < '01/01/2015'::date;
Временно приостановить новые вставки / обновления производственной базы данных
Скопируйте самые последние данные в новую главную таблицу
INSERT INTO child_2015 (id,counter,dt_created)
SELECT id,counter,dt_created
from old_master
where dt_created >= '01/01/2015'::date AND dt_created < '01/01/2016'::date;
Переименуйте таблицы, чтобы new_master стал производственной базой данных.
ALTER TABLE old_master RENAME TO old_master_backup;
ALTER TABLE new_master RENAME TO old_master;
Добавьте функцию для операторов INSERT в old_master, чтобы данные передавались в правильный раздел.
CREATE OR REPLACE FUNCTION fn_insert() RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.dt_created >= DATE '2015-01-01' AND
NEW.dt_created < DATE '2016-01-01' ) THEN
INSERT INTO child_2015 VALUES (NEW.*);
ELSIF ( NEW.dt_created < DATE '2015-01-01' ) THEN
INSERT INTO child_2014 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Date out of range';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Добавьте триггер, чтобы функция вызывалась на INSERTS
CREATE TRIGGER tr_insert BEFORE INSERT ON old_master
FOR EACH ROW EXECUTE PROCEDURE fn_insert();
Установите ограничение исключения на ON
SET constraint_exclusion = on;
Повторно включите ОБНОВЛЕНИЯ и ВСТАВКИ в производственной базе данных.
Настройте триггер или cron, чтобы создавались новые разделы и обновлялась функция для назначения новых данных правильному разделу. Ссылка на эту статью для примеров кода
Удалить old_master_backup