There are a couple of other things to think about:
- One of the issues you haven't addressed is how the changes to a shift/employee propagate -- in other words, if I change the shift assignment would I normally be expecting to change it permanently or just for the next week?
- This is also a situation where the shift_id solution (despite being more 'database-y') might actually be less efficient than a more simple (but less commonly-used) strategy. In other words, have you considered a bitmap of some sort using bitwise operations to determine shift availability and prevent overlapping shifts or other shenanigans?
HTH