2011-09-05 62 views
7

我從頭開始建立日曆系統(要求,因爲我正在與Gregorian一起使用特殊類型的日曆),並且我需要一些邏輯幫助。我正在用Django和Python編寫應用程序。在日曆中重複「事件」:CPU vs數據庫

本質上,我遇到的邏輯問題是如何儘可能保持儘可能少的對象,而不會在CPU週期上運行選項卡。我感覺多態會成爲解決這個問題的方法,但我不確定如何在這裏表達它。

我有兩個基本的事件子集,重複事件和一次性事件。

重複事件將有訂戶,通知他們的變化的人。例如,如果一個班級被取消或搬到不同的地址或時間,那麼已訂閱的人需要知道這一點。有些事件每天都會發生,直到時間結束,不會被編輯,並且「恰好發生」。問題是,如果我有一個對象存儲事件信息及其重複策略,那麼取消或修改系列中的一個事件真的會搞砸了,我必須以某種方式解決這個問題,讓訂閱者意識到改變並保持這個系列作爲一個邏輯組合。

悖論:爲系列中的每個正常事件生成唯一事件對象,直到時間結束(如果它無限期地重複),如果它們都將存儲相同的信息,則無意義;然而,如果系列中的單個事件發生任何更改,我幾乎會已有在數據庫中創建一個不同的對象來表示取消。

有人可以幫我用這裏的邏輯嗎?它真的扭曲了我的想法,我不能再真正地思考了。我真的很想就如何解決這個問題提供一些建議,因爲重複事件並不是最簡單的邏輯事件(每隔一天或每M/W/F重複一次,或每個月的第一個M,或者每3個月或每年一次,或這一天的每週一次,或這一天的每月一次,或週二的上午9:00和週四的上午11點等),我會就像幫助理解重複事件的最佳邏輯路線一樣。

下面是關於如何做到這一點思想:

class EventSeries(models.Model): 
    series_name = models.TextField() 
    series_description = models.TextField() 
    series_repeat_policy = models.IHaveNoIdeaInTheWorldOnHowToRepresentThisField() 
    series_default_time = models.TimeField() 
    series_start_date = models.DateField() 
    series_end_date = models.DateField() 
    location = models.ForeignKey('Location') 

class EventSeriesAnomaly(models.Model): 
    event_series = models.ForeignKey('EventSeries', related_name="exceptions") 
    override_name = models.TextField() 
    override_description = models.TextField() 
    override_time = models.TimeField() 
    override_location = models.ForeignKey('Location') 
    event_date = models.DateField() 

class EventSeriesCancellation(models.Model): 
    event_series = models.ForeignKey('EventSeries', related_name="cancellations") 
    event_date = models.TimeField() 
    cancellation_explanation = models.TextField() 

這似乎使了一點感覺,但如上所述,這是毀了我的大腦,現在,所以,只要看起來像它會工作。 (另一個問題和問題是,如果有人想修改系列中剩下的所有事件,我該怎麼做!?!?我想我可以更改'series_default_time',然後爲所有過去的實例生成異常實例以設置它們原來的時間,但AHHHHHH !!!)

沸騰它歸結爲三個簡單的,具體的問題,我們有:

  1. 怎樣纔可以有一系列重複的事件,但允許取消和修改個別事件作爲一個整體對系列的其餘部分進行了修改,而在絕對必要時將少量對象存儲在數據庫中,絕不會爲單個事件生成對象提前?
  2. 如何以一種高度可定製的方式重複事件,而不會失去理智,因爲我可以允許事件在number of ways中重複,但再次使事情變得簡單並儘可能少地存儲對象?
  3. 我怎麼能做到以上的,允許在每個事件系列交換機使,如果它掉下來一個holiday它不會發生呢?
+5

+1爲罕見但有用的類:models.IHaveNoIdeaInTheWorldOnHowToRepresentThisField – mjhm

+0

我經常使用該字段的方式。 –

回答

1

我只想解決問題3,關於假期。

在幾個報告數據庫,我發現它很方便的定義一個表,讓我們把它稱爲「年鑑」,即對每個日期一行,在一定範圍內。如果範圍跨度爲十年,該表格將包含約3,652行。按今天的標準來看,這很小。主鍵是日期。

其他的一些列事情,例如日期是否是假日,正常工作日,或週末的一天。我知道,我知道,你可以通過使用內置函數來計算週末的東西。但事實證明,將這些東西作爲數據很方便。它使你的連接變得更簡單和更相似。

然後你有一個應用程序來填充年曆。它內置了所有的日曆怪癖,包括用於確定哪些日子是假期的企業規則。您甚至可以包含給定日期所屬的「會計月度」列,如果這與您的案例有關。應用程序的其餘部分,包括入門程序和提取程序,都像普通的舊數據一樣對待年曆。

這可能看起來不是最理想的,因爲它不是最小的。但相信我,這種設計模式在各種情況下都很有用。這是由你來決定它如何適用於你的情況。

年曆實際上是數據倉庫和星型模式設計原理的一個子集。

如果你想在CPU中做同樣的事情,你可以有一個具有諸如Almanac.holiday(date)等公共特性的「年曆」對象。

+0

對於這個用例,這很有意義。由於我計算的假期是使用有些複雜的邏輯來計算的(我們沒有在這裏處理公曆),所以在這個用例中這可能是一個好主意。由於這些類型的對象不可編輯,並且可以緩存硬核,所以這是有道理的。我可能會創建兩個表格,一個用於將日曆映射到公曆日曆,另一個用於將假期映射到日曆的日子,然後我將找到一種合併數據並獲得智能的方法。謝謝。 –

+0

是的。然而,在您的日曆表示日期中,您的Alamanac中的一列可能是表達日期的平等日期。然後,您可以在簡單的舊格利高日重新記錄事件的日期和類似日期,就像DBMS所瞭解的一樣,但可以將其與年曆一起加入,以便在日曆中向數據用戶呈現日期。 –

0

我前一段時間所面臨的確切同樣的問題你。但是,最初的解決方案不包含任何異常或取消,只是重複事件。我們建模一系列重複事件的方式是讓某些字段指示間隔類型(如每月/每週/每日),然後從給定開始日開始計算距離(如每隔2天,每2周等) 。這種重複的簡單方法並不包含太多場景,但計算重複日期非常簡單。其他重複方式也是可能的,例如cronjobs定義的方式。爲了生成重複,我們創建了一個表函數,它給出了一些用戶標識生成的所有事件重複即時動態,直到使用遞歸SQL在未來動用未來5年(如在您的方法中,對於一組重複,只有一個事件必須被存儲)。到目前爲止,這個工作非常好,可以查詢表函數,就好像單個重複實際上存儲在數據庫中一樣。它也可以很容易地擴展到排除任何取消的事件,並根據日期替換更改的事件,也可以在運行中。我不知道你的數據庫和你的ORM是否可能。

+0

這不太可能(對於我的用例),因爲我確實需要堅持儘可能少的對象。如果通過一些邏輯推理我可以想出一個只涉及少數幾個解決方案的方案,我並不認爲堅持如此多的目標是重要的。我越想到,我寫的數據模型似乎越好(上面的那個),但我仍然需要提供一種靈活的方式來處理複雜的重複,所以我認爲我需要另一個模型來表示變體重複。 –

+0

咦?你的意思可能是什麼?我不明白你怎麼能堅持不下,也許我沒有足夠清楚地解釋。 –

3

這可能會成爲一個激烈的討論,因爲日期邏輯通常是比它看起來更難,每個人都會有自己的想法如何使事情發生。

我可能會犧牲一些數據庫空間,並有模型儘可能啞(如由沒有定義異常的一系列)。重複條件可能是一些簡單的術語,必須根據您的要求進行分析(或根據您的要求)或 - KISS - 只是下一個事件發生的時間間隔。

由此您可以生成「下一個」事件,它將複製重複條件,並根據實際需要在未來生成儘可能多的事件(定義未來的最大時間窗口,以生成事件但生成事件他們只有,當有人實際上看時間intervall問題)。事件可以有一個指向父事件的指針,所以整個系列都是可識別的(就像鏈表一樣)。

模型應該有一個指標,是否一個事件被取消。 (事件仍然在數據庫中,以便將事件複製到將來)。取消整個系列將刪除事件列表。

編輯:other answers提到the dateutil package區間建設和解析,這真的很好看。

+0

爲dateutil +1。 'rrule'和'rruleset'好像可以在這裏使用。 – sandinmyjoints

1

對於我創建了一個事件序列模型,我的解決方案IHaveNoIdeaInTheWorldOnHowToRepresentThisField是使用pickled object field保存來自dateutil復發規則(rrule)在我的事件序列模型。

相關問題