我有一个“事件”(会议,生日聚会等)记录的数据库,每个事件都有一个endTime
字段。活动结束后,我想为每个过去的活动发送2-3封电子邮件。
现在,我运行一个每小时的cron作业来查找过去一小时内已结束的所有事件,所以它看起来像:
但是,当下午3:01的工作由于某种原因失败时(Heroku崩溃了我的其他api,电子邮件服务提供商关闭等),在2-3点结束的事件将不会收到电子邮件。
目前,如果电子邮件发送成功,我的数据库记录未标记为notified
。我应该这样做,所以我可以将cron脚本更改为“在当前时间notified=false
之前找到所有记录”(它捕获所有以前未发送的记录)?您是否会为您成功发送的每种电子邮件设置一个标志?
还是有一种更聪明的方法可以避免设置标志吗?
(这个问题的标题和标签到底出现了 - 建议/编辑欢迎!)
答案 0 :(得分:0)
notified
标志的问题是它需要一个索引才能使WHERE notified = FALSE
1 有效,但TRUE值仍保留在索引中,尽管从未在查询中使用过再一次。
在时间上,你将在索引中有一个小的FALSE部分(这很有用)和一个巨大的TRUE部分(它只是浪费空间)。如果您的DBMS支持它,请使用某种partial index从索引中删除TRUE:
CREATE INDEX ... WHERE notified = 0
。或者,创建一个只有一行和一个字段的额外表: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表。