2011-01-10 52 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 
; 

未经测试,但这是我想做的