开发者

How to optimize the data model for an event calendar?

I开发者_开发技巧'm building an event calendar. The basic functionnality is like this:

There are 3 states for each day, "available", "unavailable" and "confirmation needed". Each day can be set to a single state (i.e., an event). Each event can be set to be recurring either weekly or monthly, or not at all.

Each calendar is specific for an object (each object has its own calendar).

The calendars don't have an "end date": there can be an event at any given date in the future.

The data model I imagined was this:

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

This seems to be a fairly elegant way to store the data, but I'm worried about retrieval: it would be fairly complicated to get the status for a given day.

Is there a better or standard way to do this ?


Assuming that day is a start_date (otherwise I misunderstood), the format seems not bad to me. Later on maybe you will need to have start/end dates and maybe start/end time, in that case you will have to put timestamps instead.

In order to retrieve the data, I'd have a dates table created like:

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

If you need to get the appointments with the status A (available) for a given period, you can do something like

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() would be a function that checks if cday is in the scope of reccurence, like that:

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
;

Not tested but this is what I'd do


Check the iCalendar format.

http://en.wikipedia.org/wiki/ICalendar for standard format.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜