2014-09-29 61 views
1

我需要更新表中预先计算的数据可以添加/更新/删除的表中的值。insert ... select ...重复键更新+删除过时的行

我可以用

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

添加/更新预先计算表,但有一个优化的方法来删除过时的行?

+0

当你说过时你是指那些没有使用这个脚本更新的行? – 2014-09-29 16:45:20

+0

我的意思是从主表中删除的数据。从主表中删除的数据应该从预先计算的表中删除。所以基本上,是的,没有更新的数据。 – medmed 2014-09-29 16:47:02

+1

在正在删除的表上创建一个触发器,检查是否存在“孤立”行并删除它们 – Barranka 2014-09-29 16:48:24

回答

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 2014-09-29 17:33:52

+0

然而,我可能会去触发解决方案。正如我回答Andreas Wederbrand所说,“我认为这是我将如何结束这样做的过程,但我仍然需要一些脚本来清理表格,因为预先计算的数据也取决于日期(我想删除不在开始和结束之间的行结束日期)和一些计数器。“没有我想要的那么优雅,但它应该起作用。谢谢。 – medmed 2014-09-29 17:41:33

+0

@medmed您可以创建一个存储过程来删除不再需要的行,并且可以从触发器调用该存储过程。 – Barranka 2014-09-29 19:15:25

1

既然你一直在增加或更新中存在的这些其他表中的行,和你想删除不存在任何行,你为什么不只是:

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

总是在启动清洁手段你以后不必担心孤儿。

+0

我无法从此表中删除数据。这会破坏服务,直到数据恢复。 – medmed 2014-09-29 17:28:42

+0

如果你把整个陈述封装成单个交易 – Sabine 2017-03-05 00:09:34

1

您可以在维护precalculated的主表上添加用于插入,删除和更新的触发器。

当插入或更新相同的代码可以用来计算值,并出具了replace into precalculated (...) values (...)

当删除它可能是相同的,与另外,你还可以从precalculated是孤儿删除行。在这里很聪明,并使用原始删除的值为precalculated查询孤儿,而不是执行表扫描。

+0

,我认为这是我将如何结束这样做的。但是由于预先计算的数据也取决于日期(我想删除不在开始日期和结束日期之间的行)以及一些计数器,所以我仍然需要一些脚本来清理表。谢谢。 – medmed 2014-09-29 17:35:07