2009-06-03 56 views
42

我想寫一個日曆應用程序。這是真正反覆出現的項目,在DB架構的作品中引發了一些問題。我會喜歡一些關於如何組織這一點的意見。爲日曆應用程序佈置數據庫模式

如果用戶創建一個事件,並輸入它重複所有人星期一,永遠是什麼?我怎麼能將所有這些存儲在數據庫中?我無法創造無限的事件。我只是在那裏放置一張桌子,裏面有相關信息,以便我可以計算出所有事件的發生地點?如果是這樣,每次用戶查看日曆的新部分時,我都必須計算它們。如果他們翻閱了幾個月,但他們有很多經常性項目呢?

此外,模式需要處理,當用戶點擊一個項目,並說「編輯序列中的這一個」不是序列中的所有項目。然後我是否將序列中的一個項目分開?

更新1

我沒有在iCal的看着這一切。爲了清楚起見,我認爲保存允許您計算重複項目的信息,並將與順序不同的任何項目分開是將其存儲以便將其傳輸的一種好方法。但我認爲,在一個應用程序中,這太慢了,要在所有地方進行日期數學計算。

+1

「然後我將一個項目從序列中分離出來嗎?」我相信這就是iCal文件格式如何處理它。你有沒有研究過這種格式? – 2009-06-03 21:15:21

+1

這是一個很好的問題,前幾天我很想知道這件事。 – 2009-06-03 21:27:20

回答

12

我最近創建了一個日曆應用程序,這是我面臨的衆多挑戰之一。

我最終想出了一個半黑客解決方案。我創建了一個event_type列。在那一欄中,我有:「每日」,「每週」,「每月」或「每年」。我也有一個start_date和end_date列。其他的一切都是在實際的後端代碼中處理的。

如果用戶只編輯了一個事件,我從來沒有嘗試過拆分事件。這種情況沒有必要。但是,您可以通過更改第一個事件的end_date來分割事件,使用新的開始日期和原始的end_date創建新事件,最後爲您剛剛選擇編輯的事件分配事件。這個過程最終會創建3個事件。

哈哈,我知道。當時我想不出一個聰明的辦法來解決這個問題。

+0

是的,這或多或少是我曾經想過的,但是你是否因爲做所有這些日期計算而受到性能影響? – 2009-06-03 21:18:44

+0

是的,但我認爲這是必要的。我無法想出一個乾淨的方式來處理它與沒有廣泛的後端代碼的數據庫。 – JasonV 2009-06-03 21:21:26

+0

我可以獲取日曆事件調度程序數據庫模式,它可以讓我知道我可以使用哪些表格? – Tejinder 2017-11-28 06:41:57

2

按正常方式保存事件表中的重複項目,但標記爲具有適當開始/結束日期的重複項目。

如果用戶修改約會的單個實例,只需創建一個新事件,或許使用等於事件ID的「parentId」。

構建邏輯,使日曆覆蓋特定日期中具有匹配父ID的事件的任何重複事件。

有關性能的問題基本上是舊的速度與存儲問題。我真的不認爲所需的計算會超過存儲這麼多預約的空間需求。只是閱讀了數據庫優化 - 索引等。

+0

這不是我擔心的數據庫表現。這是後端代碼執行日期數學。所以,如果我說,這個事件是每個第三個星期一,從08開始,永不結束,現在是2010年,你必須弄清楚你的日曆甚至會在哪裏。也許這不像我想的那麼激烈。 – 2009-06-03 21:26:05

2

你能用兩個「緩存」表來連接兩個世界嗎?在這個表中,你預先計算了下一個X天事件的價值?

所以三個表:

recurring_event_specs 
one_time_events 
cached_recurring_events 

對於今天之內X天的日曆的任何部分,你的查詢將UNION one_time_eventscached_recurring_events

然後,如果用戶在將來嘗試查看超過X天的部分日曆,則只需進行即時日期計算。我想你可以找到一個能夠覆蓋大部分正常使用的理智的X.

cached_recurring_events表將需要每當用戶增加新的定期更新的事件 - 可能每天一次離線通過一個cron作業/計劃的任務和。但只有在沒有新的重複事件產生的日子裏。

0

要做到這一點,最好的方法是存儲基於標準的重複模式字符串(iCal)..並保留空白,如果它是單個事件。有幾個API可以解析循環模式並創建可以綁定到UI元素的事件對象....無需將任何事件存儲在數據庫中,只需要初始事件(發生)。

12

我一直在努力解決同樣的問題,而且我實際上正在玩弄上面提到的「緩存表」的想法,但後來我遇到了一個似乎還沒有被代表的備選方案(suggested here)。

建立一個包含所有事件

EventID (primary key) 
Description 
StartDate 
PeriodType - days, weeks, months, years 
PeriodFreq - # of days, weeks, etc between events 
EndDate 
... other attributes that can be modified 

然後添加一個表例外這些事件的表。此表使用由映射到事件表的EventID組成的組合鍵和用於選擇系列中特定事件的實例ID。

EventID (key) 
InstanceID (key) 
InstanceDate - the modified date of the exception 
IsCancelled - a flag to skip this date when traversing the series 
... other attributes that can be modified 

它似乎保持事件表正常化,並避免分裂系列來處理異常。

0

難道你不能每天以開始和結束時間存儲事件嗎?它會爲每天發生的事件生成大量數據(可能不是這種關係),但它可以使查詢變得更容易,並且有可能產生異常(例如,事件發生地點被燒燬或員工引人注目)。爲了生成事件的日子,我建議在前端實現ICal-ish模式。

4

爲什麼不使用Google日曆作爲此日曆應用程序的數據庫,依靠Google Calendar's API來存儲和檢索日曆事件?

Calendar API是一個可以通過顯式HTTP調用訪問的REST API;該API暴露了Google日曆Web界面中的大部分功能,因此您的日曆應用程序可以具有與Google日曆一樣多的功能(很多功能!!!)。

您的應用程序只需要爲Google API實現OAuth 2.0,通過使用單點登錄服務(如Auth0)即可輕鬆提供相應的訪問令牌。然後,您的日曆應用程序可以將這些令牌與Calendar API結合使用,以JSON格式提供日曆事件的無縫存儲和檢索。

用戶在自己的「新日曆」中創建活動。此日曆以專用於此應用程序的gmail帳戶的形式與您共享 - 該應用程序的gmail帳戶

基本上,谷歌日曆成爲你的數據庫,讓你可以有應用程序的Gmail帳戶不僅存儲所有應用程序的活動,但也允許您使用一個直觀的界面查看和編輯這些事件。