2013-06-12 54 views
0

我有一個「事件」(會議,生日聚會等)記錄的分貝,每個事件都有一個endTime字段。活動結束後,我想爲每個過去的活動發送2-3封電子郵件。根據每個db記錄時間戳發送通知電子郵件

現在,我運行一個小時的cron作業的發現,在過去一小時內結束所有的事件,所以它看起來是這樣的:

  • 在下午2點01分:發現所有事件之間1-2pm結束,發送電子郵件
  • 在下午3:01:找到下午2-3點之間結束所有事件,發送電子郵件
  • 在下午4:01:找到3-4pm之間結束所有事件,發送電子郵件
  • 日下午5:01。 ..

然而,說下午3點01分工作因某種原因失敗(Heroku崩潰了我的休息api,電子郵件服務提供商崩潰等),在2-3pm結束的事件將不會收到電子郵件。

目前,如果電子郵件發送成功,我的db記錄未標記爲notified。我應該這樣做,這樣我就可以將cron腳本更改爲「查找當前時間之前的所有記錄,其中notified=false」(捕獲所有以前未發送的記錄)?你會爲你發送的每種電子郵件成功設置一個標誌嗎?

還是有一個更聰明的方法,避免設置標誌?

(這是地獄來了的標題和標籤這個問題 - 建議/編輯歡迎!)

回答

0

notified標誌的問題是,它需要一個索引只是爲了讓WHERE notified = FALSE 有效的,但儘管從未再次用於查詢,TRUE值仍保留在索引中。

隨着時間的推移,你會在索引(這是有用的)和一個巨大的TRUE部分(這只是浪費空間)有一個小的FALSE部分。如果你的DBMS支持的話,使用partial index某種從索引中刪除TRUE:

或者,創建一個額外的表中的一行和一個字段:LAST_SENT ,並更新該字段時通知一堆已經成功地發送。這當然會阻止按順序發送通知,並且您需要小心處理部分故障,因爲您不能跳過不成功的通知。


更換FALSE與任何適合你的數據庫。

如果你的表使用自動遞增的整數作爲主鍵,考慮使用的LAST_SENT而不是時間戳,以避免邊緣情況下,時間戳可能不是唯一的。

+0

我仍然不知道,如果每封郵件類型添加字段(和索引)是走不過的方式?如果我確實去做,那麼這些將會有所幫助。 – thatmarvin

+0

@thatmarvin另一種替代方法是簡單地有兩個表格:一個用於發送,另一個用於未發送的通知。發送通知時,只需將其從一個表移動到另一個表。顯然,如果你需要一個跨越兩個表的鍵並且可以複製FK,這可能會有問題,但是如果你的DBMS支持的話,這可以通過對錶進行分區來緩解(所以它仍然是邏輯上的一個表)。 –

+0

我的桌子還很小,所以我現在想要最簡單的解決方案。我現在實際上在使用MongoDB,但計劃很快切換到postgresql(因此是誤導標籤)。我正在尋找的答案是「是的,你肯定需要旗幟才能做到這一點」,或者「不,有沒有旗幟就可以做的其他事情」。聽起來像你在說「是」! – thatmarvin

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表中。

相關問題