Storing Business Hours in a Database

后端 未结 6 656
迷失自我
迷失自我 2020-12-04 07:05

I\'m currently trying to work out the best way to store a business\' hours of operation in a database.

For example:

Business A has the following hours of ope

相关标签:
6条回答
  • 2020-12-04 07:36

    I have learned that if you want to have google data markup recognize your data you should follow these guidelines:

    https://schema.org/openingHours

    http://schema.org/OpeningHoursSpecification Contains "valid dates", which is very useful for some businesses.

    https://schema.org/docs/search_results.html#q=hours

    You should be fine without a primary key, unless you are allowing businesses to share the same hours with the join table - interestingly eventually you would have a finite amount of combinations; I'm not sure how many that would be :p

    With one of my projects I used the columns:

    [uInt]business_id, [uTinyInt]day, [char(11)]timeRange

    If you want to support OpeningHoursSpecification then you'll need to add validFrom and validThrough.

    Time Range is formatted like: hh:mm-hh:mm

    Here's a function that parses it, you can also modify this function to parse just a single open/close, if you keep them as separate columns in the DB.

    Out of my experience I would recommend that you allow multiple times within a day, allow for a way to tell if they are explicitly closed on that day, or opened 24 hours or 24/7. I had mine say that if there was a day missing in the DB then the business was closed that day.

    /**
     * parseTimeRange
     * parses a time range in the form of
     * '08:55-22:00'
     * @param $timeRange 'hh:mm-hh:mm' '08:55-22:00'
     * @return mixed ['hourStart'=>, 'minuteStart'=>, 'hourEnd'=>, 'minuteEnd'=>]
     */
    function parseTimeRange($timeRange)
    {
        // no validating just parsing
        preg_match('/(?P<hourStart>\d{1,2}):(?P<minuteStart>\d{2})-(?P<hourEnd>\d{1,2}):(?P<minuteEnd>\d{2})/', $timeRange, $matches);
    
        return $matches;
    }
    
    0 讨论(0)
  • 2020-12-04 07:38

    One situation that isn't covered by this schema is several opening periods in a day. For example, the local pub is open 12:00-14:30 and 17:00-23:00.

    Maybe a theatre box office is open for a matinee and an evening performance.

    At that point you need to decide if you can have several entries for the same day, or if you need to represent different hours in the same row.

    What about opening times that cross midnight. Say a bar is open 19:00-02:00. You couldn't just compare the opening and closing times with the time you want to test.

    0 讨论(0)
  • 2020-12-04 07:40

    It sort of depends on what you need to store it for and what the real-world data could look like.
    If you need to be able to determine if the business is open at a certain point then it may be a bit awkward to query the scheme as laid out. More importantly, though, is: Would you ever need to cater for a mid-day closure?

    Some options include;

    • A scheme like what you have, but with the option to have multiple periods for the same day. It would cater for the lunch break, but would make it awkward to run a query that gives you the opening hours for a given day, say for presentation to a user.
    • A bitmap style approach; "000000000111111110000000" for 9-5. The downside to this approach is that you have to choose a specific granularity, i.e. whole hours or half-hours or, indeed, minutes. The finer the granularity, the harder the data is to read for a human. You could use bitwise operators to store this value as a single number rather than a string of integers, but again it hurts legibility.
    0 讨论(0)
  • 2020-12-04 07:43

    Might think about factoring in holidays by including additional fields for month of year/day of month/week of month. Week of month has some minor subtlties "last" could for example be week 4 or 5 depending on the year.

    0 讨论(0)
  • 2020-12-04 07:49

    Overall, I see nothing wrong with this. Except...

    1. I would store the day of week as an integer using whatever numbering system your native programming language uses (in its libraries). This will decrease the size of the database and remove string comparisons from your code.

    2. I would probably put the foreign key to the business table right here in this table. That way you won't need a link table.

    So I guess I would do:

    CREATE TABLE "business_hours" (
         "id" integer NOT NULL PRIMARY KEY,
         "business_id" integer NOT NULL FOREIGN KEY REFERENCES "businesses",
         "day" integer NOT NULL,
         "open_time" time,
         "close_time" time
    )
    

    In my business logic, I would enforce a constraint that every "business" has at least 7 "business hours". (At least because Jon Skeet is right, you might want holiday hours.) Though you may want to relax this constraint by simply leaving off "business hours" for days that the business is closed.

    0 讨论(0)
  • 2020-12-04 07:54

    Most of results works fine for the given scenario, but it wont be as effective if you have periods that runs through multiple days, eg. 8:00 AM ~ 2:00 AM, then I recommend using a multi period design.

       0: [
             id: 1,
             business_id: 1,
             open: true,
             day: 1,
             periods: [
                 0: { open: 08:00, close: 23:59 }
             ]
          ],
       1: [
             id: 2,
             business_id: 1,
             open: true,
             day: 2,
             periods: [
                 0: { open: 00:00, close: 02:00 }
                 1: { open: 08:00, close: 23:59 }
             ]
          ]
    
    0 讨论(0)
提交回复
热议问题