2011-01-10 54 views
3

我正在構建活動日曆。基本功能如下:如何優化事件日曆的數據模型?

每天有3個狀態,「可用」,「不可用」和「需要確認」。每天都可以設置爲單一狀態(即事件)。每個事件可以設置爲每週或每月重複發生,或者根本不發生。

每個日曆都是特定於某個對象的(每個對象都有其自己的日曆)。

日曆沒有「結束日期」:在將來的任何給定日期都可能有事件。

我想象中的數據模型是這樣的:

Table: Calendar 
id 
user_id 

Table: Status 
id 
label 

Table: Event 
id 
calendar_id 
start_date 
status_id 
recurring -- enum type: NULL, W, or M for weekly or monthly 

這似乎是存儲數據的相當優雅的方式,但我很擔心檢索:這將是相當複雜的,以獲得地位給定的一天。

有沒有更好的或標準的方法來做到這一點?

+0

作爲地位是不是一個可爲空的布爾是否足夠?或者你想保留稍後添加不同狀態的可能性嗎? – 2011-01-10 14:57:53

回答

2

假設這一天是一個start_date(否則我誤解了),格式似乎並不壞。稍後,也許你需要開始/結束日期,也許開始/結束時間,在這種情況下,你將不得不放置時間戳。

爲了檢索數據,我倒是有一個日期表創建這樣的:

+------------+ 
| cday (PK) | 
+------------+ 
| ...  | 
| 2011-01-01 | 
| 2011-01-02 | 
| 2011-01-03 | 
| 2011-01-04 | 
| 2011-01-05 | 
| 2011-01-06 | 
| ...  | 
+------------+ 

如果你需要得到與某一時期的狀態A(提供)的約會,你可以做像

SELECT ev.* 
FROM cdays AS cd 
JOIN event AS ev ON (
    CHECK_RECCUR(cd.cday, ev.day, cd.recurring) 
) 
WHERE TRUE 
    AND cd.cday BETWEEN "given_start" AND "given_end" 
    AND ev.day < "given_end" 
; 

CHECK_RECCUR()將是,檢查是否cday是在reccurence的範圍的函數,這樣的:

CREATE FUNCTION CHECK_RECCUR(cday DATE, start_date DATE, recurring CHAR(1)) 
BEGIN 
    IF cday < start_date 
    THEN RETURN FALSE 
    END IF; 
    SET dformat = CASE recurring 
    WHEN 'W' THEN '%W' 
    WHEN 'M' THEN '%d' 
    WHEN 'Y' THEN '%m-%d' 
    ELSE '' 
    END; 
    RETURN (DATE_FORMAT(cday, dformat) == DATE_FORMAT(start_date, dformat)); 
END 
; 

未經測試,但這是我想做的