Статья хорошая, но вот это утверждение "
Партиционирование в Postgres — не так хорошо, но все же возможность есть" явно сделано человеком, который про Постгре знает только то, что это СУБД :) Я это могу утверждать однозначно и категорически, потому что с Постгре поработал немало, в т.ч. и с партициями. Поэтому просто не могу промолчать :)
Основное отличие партиций в Постгре от Мускуля в том, что в Мускуле говоришь "хочу партиции" и СУБД сама всё делает. В Постгре же нужно самому всё настроить. Триггеры, (автоматическое) создание нужных партиций, когда они нужны, индексы, констрейнты и т.д. и т.п. Но это делаешь один раз и потом "не паришься". Хочу обратить особое внимание на то, что новые части партиции можно и нужно создавать автоматически. И сделать это очень легко. Хотя по этой вот ссылке
http://www.postgresql.org/docs/8.1/interac...rtitioning.html об этом не сказано ни слова. Но я утверждаю - это элементарно! Благо дело, собственноручно настраивал.
Затем, когда всё настроено, система "работает как хорошие швейцарские часы". И далее уже можно удалять старые части партиции или бэкапить их, чтобы можно было, при необходимости, восстановить. А вот в Мускуле придется на этом этапе "попрыгать".
Дабы не быть голословным... Вот пример функции, вызываемой триггером вставки данных в определенной таблице, которая является основной "точкой входа".
Хотел всё показать "красиво", т.е. как оно было сделано... Но каменты неправильно обрабатываются нашим "подсветчиком" для SQL. Он видит два минуса и потом до самого конца кода считает, что это был камент :( Поэтому показываю две версии.
Я думаю, что все, кому надо, разберутся в коде :) Только несколько пояснений сделаю.
* Имя таблицы определяется динамически, исходя из записываемых данных, с помощью вспомогательных функций, написанных мной (их кода тут нету).
* Используемый иксепшен ловит состояние '42P01', т.е. когда делается попытка писать в несуществующую таблицу. Эта таблица тут же создается (включая индексы и констрейнты) и данные пишутся уже в неё. Если же таблица существует, то данные записываются и блок иксепшион не используется.
* Функция get_uniq_table_name() возвращает строку типа "2012_m05", содержащую год и месяц, на основании переданной даты.
* Знак || (две вертикальных черты) означает в Постгре конкатенацию строк.
* Функция get_month_days() возвращает массив из 2-х элементов, содержащий даты начала и конца текущего месяца, в формате YYYY-MM-DD. Да-да, в Постгре можно работать с массивами :) Тут очень многое можно из того, чего нету в Мускуле.
1. Без каментов, но с подстветкой кода.
CREATE OR REPLACE FUNCTION block_180_insert_trigger()
RETURNS trigger AS
$BODY$
DECLARE
new_table varchar(40);
uniq_name varchar(20);
d varchar(10) array[2];
BEGIN
uniq_name := get_uniq_table_name( NEW.date_ );
new_table := 'basket.block_180_' || uniq_name;
BEGIN
EXECUTE 'insert into ' || new_table || ' select $1.* ' USING NEW;
EXCEPTION WHEN SQLSTATE '42P01' THEN
BEGIN
EXECUTE 'create table ' || new_table || '() inherits (block_180) with(autovacuum_analyze_threshold=8000, autovacuum_vacuum_threshold=8000)';
EXECUTE 'CREATE INDEX block_180_date_' || uniq_name || ' ON ' || new_table || ' USING btree (date_, omc, bsc, h )';
d := get_month_days( NEW.date_ );
EXECUTE 'alter table ' || new_table || ' add check (date_ between ''' || d[1] || ''' and ''' || d[2] || ''' ) ';
EXECUTE 'insert into ' || new_table || ' select $1.* ' USING NEW;
END;
END;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION block_180_insert_trigger()
OWNER TO postgres;
2. С каментами, но без подсветки кода. В функции все каменты оставлены, какие были, ничего нового не писал.CREATE OR REPLACE FUNCTION block_180_insert_trigger()
RETURNS trigger AS
$BODY$
DECLARE
new_table varchar(40);
uniq_name varchar(20);
d varchar(10) array[2];
BEGIN
-- определяем имена таблиц для записи данных
uniq_name := get_uniq_table_name( NEW.date_ );
new_table := 'basket.block_180_' || uniq_name;
BEGIN -- блок вставки
EXECUTE 'insert into ' || new_table || ' select $1.* ' USING NEW;
EXCEPTION WHEN SQLSTATE '42P01' THEN
BEGIN -- создаем таблицу, если нужно
EXECUTE 'create table ' || new_table || '() inherits (block_180) with(autovacuum_analyze_threshold=8000, autovacuum_vacuum_threshold=8000)';
EXECUTE 'CREATE INDEX block_180_date_' || uniq_name || ' ON ' || new_table || ' USING btree (date_, omc, bsc, h )';
-- настройка дат для CONSTRAINT
d := get_month_days( NEW.date_ );
EXECUTE 'alter table ' || new_table || ' add check (date_ between ''' || d[1] || ''' and ''' || d[2] || ''' ) ';
-- пишем повторно
EXECUTE 'insert into ' || new_table || ' select $1.* ' USING NEW;
END; -- таблица создана
END;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION block_180_insert_trigger()
OWNER TO postgres;
_____________
*
Хэлп по PHP*
Описалово по JavaScript *
Хэлп и СУБД для PostgreSQL*
Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги. *
"накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)