2014-09-29 7 views
1

Мне нужно обновить таблицу с предварительно рассчитанными значениями из таблиц, где данные могут быть добавлены/обновлены/удалены.insert ... select ... при повторном обновлении ключа + удалить устаревшие строки

я мог бы использовать

insert into precalculated(...) 
select ... from ... 
on duplicate key update ... 

добавить/обновить предварительно рассчитанную таблицу, но есть оптимизированный метод для удаления устаревших строк?

+0

Когда вы говорите, что вы устарели, вы имеете в виду строки, которые не обновляются с использованием этого скрипта? –

+0

Я имею в виду данные, которые были удалены из основных таблиц. Данные, удаленные из основных таблиц, должны быть удалены из предварительно рассчитанной таблицы. так что в принципе, да, данные, которые не были обновлены. – medmed

+1

Создайте триггер на удаляемой таблице, которая проверяет наличие «сиротских» строк и удаляет их – Barranka

ответ

0

Возможно, я нашел свое решение, используя переименование.

так в основном, я буду делать простую вставку выбрать временную таблицу, а затем

rename precalculated to precalculated_temprename, precalculated_temp to precalculated, precalculated_temprename to precalculated_temp; 
truncate precalculated_temp; 

нужны некоторые тесты, но это, кажется, операция переименования быстро и атомная.

1

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

Там не хватает информации в вашем вопросе, чтобы разработать процедуру, но я могу дать вам небольшой пример:

delimiter $$ 
create procedure delete_orphans() 
begin 
    declare id_orphan int; 
    declare done int default false; 
    declare cur_orphans cursor for 
     select distinct d.id 
     from data as d 
      left join precalculated as p on d.id = p.id 
     where p.id is null; 
    declare continue handler for not found set done = true; 
    open cur_orphans; 
    loop_delete_orphans: loop 
     fetch cur_orphans into id_orphan; 
     if done then 
      leave cur_orphans; 
     end if; 
     delete from data where id = id_orphan; 
    end loop; 
    close cur_orphans; 
end$$ 
delimiter ; 

Эта процедура удалит все строки в data таблицы, которая не имеет по крайней мере один родственный строка в таблице precalculated.

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

Вы можете вызвать эту процедуру с триггера, если хотите (с помощью call delete_orphans()).

Надеюсь, это поможет.

+0

Это наоборот.Я не хочу удалять из предварительно подсчитанных строк, которые были удалены из основных таблиц/больше не используются. во всяком случае, да, я могу сравнивать данные, используя левое соединение и удалять строки из предварительно рассчитанного, но мне нужно было знать, могу ли я найти что-то более элегантное. похоже, не ... – medmed

+0

Однако я могу пойти на триггерное решение. как я ответил Андреасу Ведербранду: «Я думаю, что так я закончу это, но мне все равно понадобятся некоторые скрипты для очистки таблицы, поскольку предварительно рассчитанные данные также зависят от даты (я хочу удалить строки, которые не находятся между началом и дата окончания) и некоторые счетчики. ". не такой элегантный, как хотелось бы, но он должен работать. Спасибо. – medmed

+0

@medmed Вы можете создать хранимую процедуру для удаления ненужных строк, и вы можете вызвать эту хранимую процедуру из вашего триггера. – Barranka

1

Поскольку вы всегда добавления или обновления строк, которые существуют в этих других таблицах, и вы хотите, чтобы удалить все строки, которые не существуют, то почему бы вам не просто:

DELETE FROM precalculated 
insert into precalculated(...) 
select ... from ... 
on duplicate key update ... 

Всегда начиная чистые средства вам не придется беспокоиться о сиротах позже.

+0

Я не могу удалить данные из этой таблицы. что приведет к разорению службы до тех пор, пока данные не будут восстановлены. – medmed

+0

это не будет, если вы инкапсулируете весь оператор в одну транзакцию – Sabine

1

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

При установке или обновлении и тот же код может быть использован для вычисления значений и выдачи replace into precalculated (...) values (...)

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

+0

Я думаю, что так я закончу это. Но мне все равно понадобятся некоторые скрипты для очистки таблицы, так как предварительно рассчитанные данные также зависят от даты (я хочу удалить строки, которые не находятся между датой начала и окончания) и некоторыми счетчиками. Благодарю. – medmed

Смежные вопросы