views:

93

answers:

4

I'm creating a web application wherein users should be able to specify their weekly schedule. Here's my DB model for that:

id
user_id
day
from
to

day is an enum of 0-6 (0 for Sunday, 1 for Monday, and so on). from and to represent minutes from midnight. So, 0 means midnight, 1 means 12:01am, 2 means 12:02am, etc.

Is this a good design? Any potential problems with it?

What if I wanted the ability to display more than a week? How would I handle that? Right now, I'm just displaying weekly work schedule, but it might be nice to be able to specify more.

+2  A: 

On a first thought I would try to make the design a bit more open. Something like

id
User_id
Date
Start_Time
End_Time

This way you do not limit yourself to one week. Besides, working with dates and times makes it easier to do calculations. Having them it is pretty easy to get the day of the week, minutes from midnight, etc.

Using this you can also easily get the week number which would allow you to show the user their schedule by just choosing the week of the year and/or its start dates.

This design supposes you will not have schedules starting on a day and ending on the next one. In that case you would need a Start_Date and an End_Date.

Hope this helps

Guillem Vicens
@Guillem: I need to show a weekly schedule. That is the primary goal. With your design, how would I show `Monday, 9am-5pm`? I don't see this as a date at all. My design can handle schedules starting on a day and ending on the next one: it simply needs to make 2 entries.
StackOverflowNewbie
Generally speaking I have to agree with Dave. The design you proposed is a closed one which makes difficult to introduce changes in your app. In my humble opinion it is better to just store the raw data you need (datetime fields) and use datetime functions (which almost every database has) to convert to weekdays, extract hours and minutes or whatever you need. In your design you would need to create your own functions to manage all that and introduce unnecessary complications. Also, with your design you would have it hard to compare different weeks while Dave's or mine make it much easier.
Guillem Vicens
+1 Nice, simple answer. Dave's edited answer includes examples of the `DATE_FORMAT` function to return both day of week and time values from datetime fields.
Mark Bannister
@Guillem, the user can't use DATETIME because (I think) he's trying to design a single weekly schedule per worker rather than a perpetual calendar. In other words, MON the worker is scheduled from 9am to 3pm and again from 6pm to 8pm. That's every single Monday, not just a particular one.
Larry Lustig
@Larry, I understand he wants to show a week schedule, but he also wants the ability to show more than 1 week. He explicitly asks how he could show such data (guess for a 2-week or month schedule) and that excludes that all Mondays have to be the same. Either way, using date fields makes both versions simpler to create and manage than using adhoc types and functions.
Guillem Vicens
+2  A: 

Please don't reinvent the wheel. This is one of the most powerful thinking on programming and developing anything.

What I mean here is, everytime you have the possibility to rely on built-in or native type, you should use it. On fields day, from and to, you can and should consider using appropriate native types, like Date, Datetime, Timestamp.

Also, if you need retrieving, filtering and so forth on these data, you can use built-in functions.

This kind of thinking on design can improve reliability on data, and make you programming easier, hence you count on functions and data types proper, tested, and widely adopted.

I would do this database like:

id -- autoincrement
Start -- datetime
End --datetime

I suppose you have a Users table. And I would add one more table, UsersSchedule, like:

user_id -- FK to users
schedule_id -- FK to schedule

Thus, many users can be registered to the same meeting or event. Of course, this can go even further, and add other control fields like EventName, EventPromoter (user_id from proponent user), Invites(user-id list of people invited to event), Atendees (user_id list of people who confirmed/atended the event)... but this decision is up to you.

Note that I would heavily use DateTime functions (http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html) in order to save on logic programming, like check today's events scheduled for a particular user, conflicting events for a particular user, and so on.

Well, I think you got the idea.

EDIT

Supposing you have one entry like:

id   |        start        |        end
45   | 2010-10-25 09:00:00 | 2010-10-25 18:00:00

You can run the query:

SELECT CONCAT(
DATE_FORMAT(start, '%a'), ', ',
DATE_FORMAT(start, '%l%p'), ' - ',
DATE_FORMAT(end, '%l%p')
) as Event FROM schedule WHERE id = 45;

Which will give you the following output:

Mon, 9AM - 6PM

Done.

Dave
@Dave: I have the same question for you as I had for Guillem: how do I represent `Monday, 9am-5pm`? All I have is day of week and time range. I don't think that translate to a date.
StackOverflowNewbie
I think you didn't get my point right. I didn't tell to NOT USE programming for absolutely nothing, but rely on safe types and functions you can. Well, but if you really want that, you can (despite at this point I disagree with this approach). Along with DAYOFWEEK and time range you can also count with DATE_FORMAT (http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-format) function. You can use it with other functions. See my edit.
Dave
@Dave, I'm still a bit confused with your example. What is the significance of `2010-10-25`? Yes, that's a Monday, but I am not interested in that specific Monday; I am interested in all Mondays. An example schedule would be like this: "Every Monday from 9am-6pm" (there is no specific date attached to it).
StackOverflowNewbie
Check your question. You wrote "What if I wanted the ability to display more than a week? How would I handle that? Right now, I'm just displaying weekly work schedule, but it might be nice to be able to specify more.". I gave you something more specific, abstract and powerful. I'm not sure about your application.
Dave
But even not so sure about your application (and thus, one good design to point), if you want not use dates, keep at least the concepts I showed with time fields and functions to make your design and life easier. Using "2" to represent 12:02 AM isn't a good design, hence you have better options to do it.
Dave
+2  A: 
PerformanceDBA
@PerformanceDBA: you have mistaken my "request for clarification" for "arguing". I have asked the question because I do realize there is potentially a problem with my approach. What apparently I am not making clear (or not understanding from the proposed solutions) is that I really only need to represent 1-week's schedule (Sunday to Saturday, no particular date). The "What if I wanted the ability to display more than a week?" question was to point out that my solution (which I think works for what I need) won't work if I wanted to expand later on.
StackOverflowNewbie
With regards to the proposed solutions of using Date, I still don't see how I can attach a date to a Sunday-Saturday schedule. There is no year, month, or day (e.g. 13th) information associated with the information I am trying to store. I don't understand how I can use Date.
StackOverflowNewbie
Responses in the main post
PerformanceDBA
+1  A: 

Okay, I think where the other answerers are getting off track is that they're trying to design a perpetual calendar. I think you only want to design a system that shows the regular, repeating weekly schedule for, for instance, a worker.

For that use, a regular, repeating weekly schedule, your design is okay. I would make FROM and TO into TIME columns rather than integers, but that's about it.

If you intend to track the amount of time people actually did work you will have to implement a second table for that more along the lines of what the other users have mentioned.

Larry Lustig
StackOverflowNewbie
Your design is good for that purpose (except I'd use TIME instead of INTEGER). In that context I don't understand what "displaying more than one week" means, there _is_ only a single week in this design.
Larry Lustig