Есть ли способ установить максимальное количество строк в базе данных PostgreSQL? - PullRequest
0 голосов
/ 07 ноября 2018

Вопрос довольно прост. Есть ли способ динамически ограничить максимальное количество строк в базе данных Postgres?

Я не думал, что это возможно, пока не увидел, что Героку это делает. После некоторых исследований я нашел способ с триггерами:

CREATE OR REPLACE FUNCTION check_number_of_row()
RETURNS TRIGGER AS
$body$
BEGIN
    -- replace 100 by the number of rows you want
    IF (SELECT count(*) FROM your_table) > 100
    THEN 
        RAISE EXCEPTION 'INSERT statement exceeding maximum number of rows for 
this table' 
    END IF;
END;
$body$
LANGUAGE plpgsql;

CREATE TRIGGER tr_check_number_of_row 
BEFORE INSERT ON your_table
FOR EACH ROW EXECUTE PROCEDURE check_number_of_row();

Но это не совсем то, что мне нужно. Он ограничивает количество строк таблицы максимальным числом STATIC, поэтому мне пришлось бы перебирать все таблицы, и это выглядит как довольно грязный вариант. И я даже не думал о том, как динамически установить это максимальное число.

Я думал о выполнении ежедневной / еженедельной работы cron, чтобы проверить все базы данных, подсчитать общее количество строк и посмотреть, находится ли он в пределах лимита, но если есть более эффективный способ, я возьму его.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Поскольку SELECT count(*) является очень дорогой операцией, я не думаю, что будет хорошей идеей запускать ее при каждом изменении данных. Кроме того, количество строк не скажет вам много о размере таблицы.

Мой подход заключается в использовании триггера с использованием pg_total_relation_size(), например:

CREATE OR REPLACE FUNCTION size_trig() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN
   IF pg_total_relation_size(TG_RELID) > (TG_ARGV[0])::bigint THEN
      RETURN NULL;
   ELSE
      RETURN NEW;
   END IF;
END;$$;

CREATE TRIGGER size_trig BEFORE INSERT ON big
   FOR EACH ROW
   EXECUTE PROCEDURE size_trig(819200);

Это ограничило бы общий размер таблицы, включая индексы и таблицу TOAST, до 100 блоков, и это сравнительно дешево.

Вам все еще нужно определить триггер для всех таблиц, которые вы хотите проверить, но нет никакого способа изменить PostgreSQL.

Вы видите, что вы можете динамически устанавливать предел для каждой таблицы. Вы также можете найти решение, которое использует таблицу соответствия для ограничения размера.

0 голосов
/ 08 ноября 2018

Я не думал, что это возможно, пока не увидел, что Героку это делает.

Это не совсем точно. Ограничения строки базы данных для уровня хобби Heroku не ограничены жестко. Иными словами, когда вы превышаете 10 000 или 10 000 строк в hobby-dev или hobby-basic, ничто не может остановить запись немедленно. Heroku предоставляет 7-дневное окно по электронной почте, чтобы подсчитать количество под квотой, иначе они заблокируют доступ для записи. Если ваши цели состоят в том, чтобы просто иметь хедз-ап и соответственно приспособиться, у них уже есть хорошая система для этого.

Однако, к вашему вопросу, учитывая, что Heroku Postgres (особенно актуально для баз данных хобби) довольно заблокирован, я не думаю, что у вас будет уровень контроля, необходимый для реализации того, что вам нужно, без того, чтобы сделать его более грязным, чем что у вас есть в вашем вопросе.

...