views:

178

answers:

2

I'm working on a project that will require me to implement a calendar. I'm trying to come up with a system that is very flexible: can handle repeating events, exceptions to repeats, etc. I've looked at the schema for applications like iCal, Lotus Notes, and Mozilla to get an idea of how to go about implementing such a system. Currently I'm having trouble deciding what is the best way to handle exceptions to repeating events. I've used databases quite a bit but don't have a ton of experience with really optimizing everything so I'm not sure which method of the two I'm considering would be optimal in terms of overall performance and ability to query/search:

  1. Breaking the repeating event. So taking the changing the ending date on the current row for the repeating event, inserting a new row with the exception, and adding another row continuing the old sequence.
  2. Simply adding an exception. So adding a new row with some field that indicates it as an override.

So here is why I can't decide. Method one will result in a lot more rows since each edit requires 2 extra rows as apposed to only one row by the second method. On the other hand I think the query to find an event would be much simper, and thus possibly faster(?) using the first method. The second method seems like it will require more calculating on the application server since once you get the data you'll have to remove the intersection of the two rows. I know databases are often the bottleneck for websites and while I'm sure a lot of you are thinking either is fine because your project will probably never get large enough for the difference in efficiency to really matter, I'd still like to implement the best solution. So what method would you guys pick, or would you do something completely different?

Also, as a side note I'll be using MySQL and PHP. If there is another technology that you think would be better suited for this, especially in the database area, please mention it.

Thanks for the advice.

A: 

Events are not permanent, are subject to change or termination.

You should insert a row for each date in the event and, upon editing a repeated event, give the option to edit all instances of the event or just one.

When doing this, you should really only need an extra field to indicate if the event is active or not.

When properly indexed, this will not make a considerable difference on your queries.

An example would be:

SELECT * FROM events WHERE event_id = 123 AND active = 1;

On which case you'd be required to index the event_id and active columns.

andre
What exactly does active mean? Because say you have a repeating event but you don't want it to repeat on a certain day. The row that holds the data for how the event should be repeated is still active and the exception added would be active too. In short every row in the database would be active... if it wasn't necessary it would just be deleted.
blcArmadillo
Active means that the event will take place on that date (was not cancelled, rescheduled, there is no repeating exception to it).If you had an event that "fires" every Saturday but not on June 19th 2010, you would insert rows for every day the event "fires" and mark that date as inactive.It shouldn't be deleted because something may change and you want that event to also fire on that date, instead of adding a new event you can just edit the existing one and enable that date.
andre
I see now. I wasn't planning on creating an entry for each day that event should fire but rather a single row that my code could then easily enumerate and figure out the days. Say for example you have an event that repeats for ever... you can't add an infinite number of rows to your db. I do see you what you meant now though. Thanks for the clarification.
blcArmadillo
You can ask the user how long does the event repeat itself. Even if it repeats daily for the next 100 years and the user adds 200 events, I doubt you'll have a problem, it's only ~7 million rows :)
andre
A: 

I've decided to just enter a row with the exceptions and use code to remove them from the repeating set. It'll be awhile before I'm done with it but I'll try and remember to post back here with some performance results when it's all done.

blcArmadillo