根据每个db记录时间戳发送通知电子邮件

时间:2013-06-12 04:01:42

标签: sql database email database-design cron

我有一个“事件”(会议,生日聚会等)记录的数据库,每个事件都有一个endTime字段。活动结束后,我想为每个过去的活动发送2-3封电子邮件。

现在,我运行一个每小时的cron作业来查找过去一小时内已结束的所有事件,所以它看起来像:

  • 下午2:01:查找所有在1-2pm之间结束的活动,发送电子邮件
  • 下午3:01:查找所有在2-3pm之间结束的活动,发送电子邮件
  • 下午4:01:查找所有在3-4pm之间结束的活动,发送电子邮件
  • 下午5:01:...

但是,当下午3:01的工作由于某种原因失败时(Heroku崩溃了我的其他api,电子邮件服务提供商关闭等),在2-3点结束的事件将不会收到电子邮件。

目前,如果电子邮件发送成功,我的数据库记录未标记为notified。我应该这样做,所以我可以将cron脚本更改为“在当前时间notified=false之前找到所有记录”(它捕获所有以前未发送的记录)?您是否会为您成功发送的每种电子邮件设置一个标志?

还是有一种更聪明的方法可以避免设置标志吗?

(这个问题的标题和标签到底出现了 - 建议/编辑欢迎!)

2 个答案:

答案 0 :(得分:0)

notified标志的问题是它需要一个索引才能使WHERE notified = FALSE 1 有效,但TRUE值仍保留在索引中,尽管从未在查询中使用过再一次。

在时间上,你将在索引中有一个小的FALSE部分(这很有用)和一个巨大的TRUE部分(它只是浪费空间)。如果您的DBMS支持它,请使用某种partial index从索引中删除TRUE:

或者,创建一个只有一行和一个字段的额外表:LAST_SENT 2 ,并在成功发送一堆通知时更新该字段。这当然会排除无序发送通知,并且您需要仔细处理部分失败,因为您不能跳过不成功的通知。


1 将FALSE替换为适合您数据库的任何内容。

2 如果您的表使用自动递增的整数作为主键,请考虑将其用于LAST_SENT而不是时间戳,以避免时间戳可能不唯一的边缘情况。

答案 1 :(得分:0)

CREATE TABLE events_tbl
(
    e_id    NUMBER
,   e_date  DATE
,   e_info  VARCHAR2(4000)
);

INSERT INTO events_tbl VALUES (43, '2000-01-01 01:10:00', 'event1');
INSERT INTO events_tbl VALUES (44, '2000-01-01 01:15:00', 'event2');
INSERT INTO events_tbl VALUES (45, '2000-01-01 01:20:00', 'event3');
INSERT INTO events_tbl VALUES (46, '2000-01-01 01:25:00', 'event4');

INSERT INTO events_tbl VALUES (47, '2000-01-01 02:10:00', 'event5');
INSERT INTO events_tbl VALUES (48, '2000-01-01 02:15:00', 'event6');
INSERT INTO events_tbl VALUES (49, '2000-01-01 02:20:00', 'event7');
INSERT INTO events_tbl VALUES (50, '2000-01-01 02:25:00', 'event8');

/* table that holds information about sent events */
CREATE TABLE events_sent_tbl
(
    s_e_id NUMBER
,   s_date DATE
);

INSERT INTO events_sent_tbl VALUES (43, '2000-01-01 02:01:00');
INSERT INTO events_sent_tbl VALUES (44, '2000-01-01 02:02:00');

SELECT  *
FROM    events_tbl
WHERE   TO_NUMBER(TO_CHAR(e_date, 'MMDDHH24MiSS')) BETWEEN 0101010000 AND 0101015959
AND     NOT EXISTS
        (
            SELECT  1
            FROM    events_sent_tbl
            WHERE   e_id = s_e_id
        )
;
/*
45  2000-01-01 01:20:00 event3
46  2000-01-01 01:25:00 event4
*/

使用:

  • 要发送的活动
  • 已发送事件

...在收藏中。将events_tbl和events_sent_tbl读入集合。在集合中发送数据和更新信息。将FORALL转储到events_sent_tbl表。