SQL триггер для удаления старых результатов - PullRequest
1 голос
/ 01 октября 2008

У нас есть база данных, которую мы используем для хранения результатов тестирования для встроенного устройства. Существует таблица со столбцами для различных типов сбоев (подробности не имеют значения), а также первичный ключ 'keynum' и столбец 'NUM_FAILURES', в котором указано количество сбоев. Мы храним пропуски и неудачи, поэтому у пропуска в NUM_FAILURES '0'.

Чтобы база данных не росла без границ, мы хотим сохранить последние 1000 результатов плюс любые 50 последних сбоев, выходящих за пределы 1000. Таким образом, в худшем случае таблица может содержать 1050 записей. , Я пытаюсь найти наиболее эффективный триггер SQL-вставки для удаления лишних записей. В ответ я дам то, что имею, но я смотрю, может ли кто-нибудь придумать что-нибудь получше, потому что SQL не то, чем я занимаюсь очень часто.

Мы используем SQLITE3 на платформе, отличной от Windows, если это необходимо.

РЕДАКТИРОВАТЬ: Чтобы уточнить, часть, с которой у меня возникают проблемы, это УДАЛИТЬ, и, в частности, часть, связанная с последними 50 сбоями.

Ответы [ 4 ]

1 голос
/ 01 октября 2008

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

0 голосов
/ 02 октября 2008

Как насчет этого:

DELETE  
FROM  table 
WHERE ( id   > ( SELECT max(id) - 1000 FROM table ) 
        AND  num_failures   = 0 
      )
OR    id     > ( SELECT max(id) - 1050 FROM table ) 

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

0 голосов
/ 01 октября 2008

Я думаю, что вы используете неправильную структуру данных. Вместо этого я бы создал две таблицы и предварительно заполнил одну 1000 строками (успехи), а другую 50 (неудачи). Поставьте основной идентификатор на каждого. Когда вы записываете результат вместо вставки новой строки, найдите значение ID + 1 для последней введенной отметки времени (возврат к нулю, если> max (id) в таблице) и обновите его новыми значениями.

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

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

0 голосов
/ 01 октября 2008

До сих пор я использовал View в сочетании с Trigger, но я не уверен, что это сработает по другим причинам.

CREATE VIEW tablename_view AS SELECT keynum FROM tablename WHERE NUM_FAILURES!='0' 
    ORDER BY keynum DESC LIMIT 50;
CREATE TRIGGER tablename_trig
  AFTER INSERT ON tablename WHEN (((SELECT COUNT(*) FROM tablename) >= 1000) or
    ((SELECT COUNT(NUM_FAILURES) FROM tablename WHERE NUM_FAILURES!='0') >= 50))
  BEGIN
     DELETE FROM tablename WHERE ((((SELECT MAX(keynum) FROM ibit) - keynum) >= 1000)
  AND 
     ((NUM_FAILURES=='0') OR ((SELECT MIN(keynum) FROM tablename_view) > keynum)));
  END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...