I’m working on a database to hold information for an on-call schedule. Currently I have a structure that looks about like this:
Table - Person: (key)ID, LName, FName, Phone, Email
Table - PersonTeam: (from Person)ID, (from Team)ID
Table - Team: (key)ID, TeamName
Table - Calendar: (key dateTime)dt, year, month, day, etc...
Table - Schedule: (from Calendar)dt, (id of Person)OnCall_NY, (id of Person)OnCall_MA, (id of Person)OnCall_CA
My question is: With the Schedule table, should I leave it structured as is, where the dt is a unique key, or should I rearrange it so that dt is non-unique and the table looks like this:
Table - Schedule: (from Calendar)dt, (from Team)ID, (from Person)ID
and have multiple entries for each day, OR would it make sense to just use:
Table - Schedule: (from Calendar)dt, (from PersonTeam)KeyID - [make a key ID on each of the person/team pairings]
A team will always have someone on call, but a person can be on call for more than one team at a time (if they are on multiple teams).
If a completely different setup would work better let me know too!
Thanks for any help! I apologize if my question is unclear. I’m learning fast but nevertheless still fairly new to using SQL daily, so I want to make sure I’m using best practices when I learn so I don’t develop bad habits.
In my view, the answer may depend on whether the number of teams is fixed and fairly small. Of course, whether the names of the teams are fixed or not, may also matter, but that would probably have more to do with column naming.
More specifically, my view is this:
If the business requirement is to always have a small and fixed number of people (say, three) on call, then it may well be more convenient to allocate three columns in
Schedule, one for every team to hold the ID of the appointed person, i.e. like your current structure:with
dtas the primary key.If the number of teams (in the
Teamtable) is fixed too, you could include teams’ names/designators in the column names like you are doing now, but if the number of teams is more than three and it’s just the number of teams inSchedulethat is limited to three, then you could just use names likeOnCallID1,OnCallID2,OnCallID3.But even if that requirement is fixed, it may only turn out fixed today, and tomorrow your boss says, “We no longer work with a fixed number of teams (on call)”, or “We need to extend the number of teams supported to four, and we may need to extend it further in the future”. So, a more universal approach would be the one you are considering switching to in your question, that is
where the primary key would now be
dt, Team.That way you could easily extend/reduce the number of people on call on the database level without having to change anything in the schema.
UPDATE
I forgot to address your third option in my original answer (sorry). Here goes.
Your first option (the one actually implemented at the moment) seems to imply that every team can be presented by (no more than) one person only. If you assign surrogate IDs to the Person/Team pairs and use those keys in
Scheduleinstead of separate IDs forPersonandTeam, you will probably be unable to enforce the mentioned “one person per team in Schedule” requirement (or, at least, that might prove somewhat troublesome) at the database level, while, using separate keys, it would be just enough to setTeamto be part of a composite key(dt, Team)and you are done, no more than one team per day now.Also, you may have difficulties letting a person change the team over time if their presence in the team was fixated in this way, i.e. with a
Schedulereference to the Person/Team pair. You would probably have to change the Team reference in thePersonTeamtable, which would result in misrepresentation of historical info: when looking at the people on call back on certain day, the person’s Team shown would be the one they belong to now, not the one they did then.Using separate IDs for people and teams in
Schedule, on the other hand, would allow you to let people change teams freely, provided you do not make(Schedule.Team, Schedule.Person)a reference to(PersonTeam.Team, PersonTeam.Person), of course.