2015-04-05 65 views
0

我有一个密码恢复系统,允许用户通过电子邮件恢复其密码。每个请求的详细信息都会插入到我的recoveries表中,并在成功恢复时删除。每次恢复创建10分钟后,每个恢复都有一个时间戳。创建10分钟后过期记录的最有效方法

我想实现一个系统,它会在10分钟后自动删除每个过期恢复。由于这个到期时间对于每一行都是不同的,这意味着使用cron作业在执行这个任务时会非常无效。

什么是最有效的方法来实现这一目标?

这里是我的代码:

$time = time(); 
$recoveries = DB::fetch("DELETE FROM `recoveries` WHERE `expiry` <= ?;", array($time)); 
+0

从这里拿参考http://stackoverflow.com/questions/14096429/how-to-delete-a-mysql-record-after-a-certain-time – Saty 2015-04-05 12:57:06

+0

我会亲自离开记录在并使用恢复的密码向登录名添加条件以匹配您的10分钟延迟。然后在夜间每天添加一个cron任务清理过期的条目。 – 2015-04-05 13:01:43

+0

@satishrajak什么时候我应该运行该代码? – mightyspaj3 2015-04-05 13:08:33

回答

0

你可以在MySQL的水平写一个触发功能,当一个条目将被插入/更新,它会触发功能,也将删除所有条目(或条目旧的然后10分钟)为这个特定的用户。 这样你不必每隔1分钟检查一次(cron job)就可以看到从数据库中删除的条目(会让你的生活变得轻松并且会节省一些资源。)

你也可以实现这种技术当任何人登录时(如果你不想在触发器级别使用触发器)

+0

但是最后一个条目怎​​么样,删除它必须等到下一个条目到达 – 2017-11-13 11:11:40

4

最有效的方法是使用视图。咦?这与问题有什么关系?那么,不要在病房后10分钟进行删除。相反,创建具有以下逻辑视图:

create view v_recoveries as 
    select r.* 
    from recoveries r 
    where expiry > date_sub(now(), interval 10 minutes); 

出于性能考虑,你想对recoveries(expiry)的指数,所以这应该是快。

然后,在您的休闲 - 每次约会过一次,或每小时一次,或每周一次 - 删除不需要的记录有:

DELETE FROM `recoveries` 
    WHERE `expiry` <= date_sub(now(), interval 10 minutes); 

这种方法有几个优点:

  • 数据的存在恰好是10分钟,而不是基于某个工作的时间安排。
  • 实际删除可能发生在系统静止时。
  • 如果cron作业执行失败,数据不会“损坏” - 也就是说,您不会收到太旧的数据。
  • 如果系统繁忙(大量插入),则插入不会与删除竞争,从而进一步降低系统速度。
+1

这个问题的最佳解决方案。 – 2017-11-13 12:17:38