What's the best way to store the days of the week an event takes place on in a relational database?

前端 未结 6 1366
独厮守ぢ
独厮守ぢ 2020-12-23 11:47

We\'re writing a records management product for schools and one of the requirements is the ability to manage course schedules. I haven\'t looked at the code for how we deal

相关标签:
6条回答
  • 2020-12-23 11:53

    I would avoid the string option for the sense of purity: it adds an extra layer of encoding/decoding that you do not need. It may also mess you up in the case of internationalization.

    Since the number of days in a week is 7, I would keep seven columns, perhaps boolean. This will also facilitate subsequent queries. This will also be useful if the tool is ever used in countries where the workweek starts on different days.

    I would avoid the lookup because that would be over-normalization. Unless your set of lookup items is not obvious or could possibly change, it's overkill. In the case of days-of-the-week (unlike US states, for example), I would sleep soundly with the fixed set.

    Considering the data domain, I don't think that a bitfield would achieve any significant space savings for you and would just make your code more complex.

    Finally, a word of warning about the domain: a lot of schools do weird things with their schedules where they "swap days" to balance out an equal number of weekdays of each type over the semester despite holidays. I am not clear about your system, but perhaps the best approach would be to store a table of the actual dates in which the course is expected to take place. This way, if there are two Tuesdays in a week, the teacher can get paid for showing up twice, and the teacher for the Thursday that was canceled will not pay.

    0 讨论(0)
  • 2020-12-23 11:54

    I don't think it's hard to write queries if we use the bit option. Just use simple binary math. I think it's the most efficient method. Personally, I do it all the time. Take a look:

     sun=1, mon=2, tue=4, wed=8, thu=16, fri=32, sat=64. 
    

    Now, say the course is held on mon, wed and fri. the value to save in database would be 42 (2+8+32). Then you can select courses on wednesday like this:

    select * from courses where (days & 8) > 0
    

    if you want courses on thu and fri you would write:

    select * from courses where (days & 48) > 0
    

    this article is relevant: http://en.wikipedia.org/wiki/Bitwise_operation

    you can put days of week numbers, as constants in your code and it will be clear enough.

    Hope it helps.

    0 讨论(0)
  • 2020-12-23 11:59

    If performance is an issue I would recommend a cleaner varation of #3.

    Link your course to a "schedule" table.

    Which is in turn linked to a days_in_schedule table.

    The days_in_schedule table has columns the schedule_name, and the date in_schedule_day. With a row for each valid day in that schedule.

    You need some time opr some clever program to populate the table but once this is done the flexibility is worth it.

    You can cope not only with "course on Fridays only", but also "first semester only", "lab closed for refurbishment in third semester" and "Canadian branch has differnet holiday schedule".

    Other possible queries are "Whats the end date of 20 day course starting 1st April", which "schedules clash most". If you are really good at SQL you can ask "what possible days are open in course xxx to a student who is already booked for course yyy" -- which I have the feeling is the real puprose of your proposed system.

    0 讨论(0)
  • 2020-12-23 12:04

    If you choose one or two, your table will not be in 1NF (first normal form) as it contains a multi-valued column.

    Nicholas has an excellent idea, although I'd disagree that his idea breaks first normal form: The data is not actually repeating, as each day is being stored independently. The only problem with it is that you have to retrieve more columns.

    0 讨论(0)
  • 2020-12-23 12:08

    A possible #4: Why does it need to be a single column? You could add 7 bit columns for each day of the week to the table. Writing SQL against it is simple, just test for a 1 in the column of your choice. And the app code reading from the database just hides this in a switch. I realize that this is not normal form and I usually spend quite a bit of time trying to undo such designs from previous programmers, but I somewhat doubt that we're going to add an eighth day to the week any time soon.

    To comment on the other solutions, I would probably groan if I encountered the lookup table. My first inclination as well was the bit field with a few custom database functions to help you write natural queries against that field easily.

    I'll be curious to read some of the other suggestions that people come up with.

    Edit: I should add that #3 and the suggestion above are easier to add indexes to. I'm not sure how one could write a SQL query like "get me all classes on Thursday" for the #1 or #2 queries that wouldn't result in a table scan. But I may just be dim tonight.

    0 讨论(0)
  • 2020-12-23 12:10

    Solution number 3 seems to be closest to what I would recommend. An extension on the idea of the look up table. Each course has one or more sessions. Create a session table with attributes: course_id, day, time, lecturer_id, room_id etc.

    You now have the ability to assign a different lecturer or room to each session of each course assuming that you may want to store this data later.

    The user interface issues are not relevant if you are considering the best database design. You can always create views for displaying the data, and for capturing the data your application can take care of the logic of capturing many sessions for each course and adding them to the database.

    The meaning of the tables would be clearer which makes long term maintenance easier.

    0 讨论(0)
提交回复
热议问题