我正在为我正在开发的网站创建一个注册系统,我遇到了一个小问题。我希望用户必须点击通过电子邮件发送给他们的链接才能使其帐户生效。当用户处于活动状态时,该行会将active
列设置为1
。
当用户注册时,将存储然后发送的电子邮件。我想要它,如果他们没有在24小时内点击链接自动删除用户行。
当然,这意味着需要在不同时间删除每一行,而不仅仅是在某个时间删除所有超过24小时的行。
我在这个网站上使用PHP和MySQL,所以任何答案都需要适应这个。
基本上,在创建行后24小时后,如果<{em> active
列为0
(默认值),我希望将其删除。当他们激活他们的帐户时,后台任务(或删除的任何内容)可以取消待检查行的待处理请求。
我听说'Cron Jobs',但是他们每隔x
运行一次任务,如果任务是相对于行运行的话我更喜欢。如果您认为这是不正确的做法,请告诉我,我会考虑使用Cron Jobs。
答案 0 :(得分:1)
你应该设置一个cron作业来删除行并每天运行一次,或者每小时运行一次 - 如果你真的想要删除这些行。
但是,您应该做的是设置一个仅显示合法用户的视图(或者您可以将此逻辑添加到访问该表的任何查询中):
create view v_signups as
select s.*
from signups s
where s.active = 1 or
s.emailsenttime >= date_sub(now(), interval 1 day);
然后,在代码中使用此视图(或等效逻辑)来查看“有效”注册。
即使您有一个cron作业,您仍然希望保持这种逻辑。这项工作将以固定的时间表运行。即使每小时一次也意味着一些用户会在25小时内闲逛,其他用户则会在24小时内闲逛。并且,事情可能发生。
该视图保证所有注册都得到平等对待,并在作业因某些原因未运行或挂起的情况下保护您的逻辑。
答案 1 :(得分:1)
当用户点击链接时,我们假设要检查此表,例如,查看用户在一小时前已点击该链接,并已激活其帐户。
SELECT s.foo
FROM signup s
WHERE s.unique_link_identifier = ?
AND s.active = 1
或者,您要检查匹配的行是否已过期...
SELECT s.foo
FROM signup s
WHERE s.unique_link_identifier = ?
AND s.active = 0
AND s.emailsentdate > NOW() + INTERVAL -24 HOUR
您可以将两个SELECT组合成一个查询
SELECT a.active
, a.foo
FROM signup a
WHERE a.unique_link_identifier = ?
AND a.active = 1
UNION ALL
SELECT s.active
, s.foo
FROM signup s
WHERE s.unique_link_identifier = ?
AND s.active = 0
AND s.emailsentdate > NOW() + INTERVAL -24 HOUR
关键是,您可以编写查询,以便在emailsentdate
后24小时内删除该行并不重要。您的查询可能会被写入,因此看起来就像行一样,就像它已被删除一样。
可以将实际删除计划为低优先级任务运行。也就是说,不需要在特定时间删除行。
考虑这一点......如果数据库因维护而关闭,那么应该在数据库关闭时运行的那些计划任务会发生什么。它们是否被跳过,或者它们都在数据库重新启动时开始运行?整个想法听起来像是意外后果的一个秘诀,而不是所有这些后果都很好。
答案 2 :(得分:0)
您可以使用MySQL event scheduler来实现此目的。你可以采取两种方式:
如果您希望每小时定期清理多个记录(完全是任意分割),您可以创建一个每小时运行一次的重复任务,以删除超过24小时的所有非活动记录。
CREATE EVENT hourly_inactive_cleanup
ON SCHEDULE EVERY 1 HOUR
DO
DELETE FROM signups
WHERE emailsenttime <= DATE_SUB(NOW(), INTERVAL 24 HOURS)
AND active = 0;
如果定期作业会定期执行而不删除任何记录,您可以在插入时创建一个任务(可能通过触发器),该任务将在24小时后触发以删除该记录,如果它是&#39 ; s不活跃。 (它实际上应该删除所有目标记录,以防上一个事件因某种原因失败。)
CREATE EVENT some_event_name
AT CURRENT_TIMESTAMP + INTERVAL 24 HOURS
DO
DELETE FROM signups
WHERE emailsenttime <= DATE_SUB(NOW(), INTERVAL 24 HOURS)
AND active = 0;
虽然我承认我对如何为此方法生成唯一的事件名称感到难过。