Триггер MySQL: возможно ли удалить строки, если таблица станет слишком большой? - PullRequest
0 голосов
/ 01 апреля 2009

При вставке новой строки в таблицу T, я хотел бы проверить, больше ли таблица, чем определенный порог, и в этом случае удалить самую старую запись (создавая какой-то FIFO в конце). 1001 *

Я думал, что мог бы просто сделать триггер, но, видимо, MySQL не позволяет изменять таблицу, в которую мы фактически вставляем:

Code: 1442  Msg: Can't update table 'amoreAgentTST01' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

Вот триггер, который я пробовал:

Delimiter $$ 
CREATE TRIGGER test 
       AFTER INSERT ON amoreAgentTST01
       FOR EACH ROW
BEGIN
    DECLARE table_size INTEGER;
    DECLARE new_row_size INTEGER;
    DECLARE threshold INTEGER;
    DECLARE max_update_time TIMESTAMP;

SELECT SUM(OCTET_LENGTH(data)) INTO table_size FROM amoreAgentTST01;
SELECT OCTET_LENGTH(NEW.data) INTO new_row_size;
SELECT 500000 INTO threshold;
select max(updatetime) INTO max_update_time  from amoreAgentTST01;

IF (table_size+new_row_size) > threshold THEN
   DELETE FROM amoreAgentTST01 WHERE max_update_time = updatetime; -- and check if not current
END IF;
END$$
delimiter ;

Есть ли у вас какие-либо идеи о том, как сделать это в базе данных?

Или это явно что-то, что нужно сделать в моей программе?

1 Ответ

4 голосов
/ 01 апреля 2009

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

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

Это имеет несколько преимуществ. Помимо избежания проблемы с триггером, которую вы видите, вы должны учитывать влияние на производительность всего, что происходит в триггере. Если вы выполняете много операций вставки, этот триггер будет выполнять эту работу и эффективно уменьшать производительность, не говоря уже о конфликте блокировок, который возникнет, когда другие процессы попытаются получить доступ к той же таблице.

Отдельный процесс, выполняющий служебную работу, минимизирует конфликт блокировок и позволяет выполнять работу как высокопроизводительную массовую операцию в транзакции.

И последнее: вам следует подумать об архивировании записей в другой таблице или базе данных, а не об их удалении.

...