I’m struggling to design a database schema that represents opening hours for buildings and their tenants. Here are the details/requirements:
Buildings:
- In general, each building’s normal business hours depend on a season (summer, winter, etc.)
- Each building has different hours.
- Numerous holidays, events, etc. will override normal business hours
Tenants:
- Tenants operate within buildings, and therefore should be constrained by building hours.
- Normal hours also depend on a season, but are not the same as its building’s seasonal hours.
- Each tenant has different hours
Ideally, I’d like to be able to query the following:
- Whether or not a building or tenant is open right now
- What are building hours today
- What are building hours for the next X days
My (unfinished) work so far has been these three tables, but I’m still having trouble creating a working solution.
[Season]
id
building_id
title
start_date
end_date
[Schedule]
id
season_id
day_of_week (0-6)
open_time
close_time
[Override]
id
schedule_id
date
is_closed
is_holiday
Thanks all for your time and input on this. All of the answers develop/refine the solution. Catcall’s idea of storing the individual dates is the easiest for us to develop a model and admin/management interface for.
Let’s look at the problem a different way. Operating hours are not essentially different for buildings and tenants. That is, the values may vary, but the idea of a building being open or not isn’t essentially different from a tenant being open or not. I created a separate schema, “hours”, to play with this idea.
It should be clear that this kind of structure, which records each day’s operating hours for every building and every tenant, will accommodate any definition of season, holidays, events, and so on. Default data can be generated with a fairly simple stored procedure. And the required queries are dead simple. (There’s a lot of value in being able to look at something and see that it’s right.)
Note that each of those queries operates on a half open interval. You can’t use the BETWEEN operator, because it operates on a closed interval.
Which requirements does this structure not accommodate?