首页 文章

在数据库中存储营业时间

提问于
浏览
60

我目前正在尝试找出在数据库中存储业务小时数的最佳方法 .

例如:

业务A有以下营业时间

  • 星期一:上午9点 - 下午5点

  • 星期二:上午9点 - 下午5点

  • 星期三:上午9点至下午5点

  • 星期四:上午9点 - 下午5点

  • 星期五:上午9点至下午5点

  • 星期六:上午9点至中午12点

  • 星期天:关闭

目前我有一个类似于以下的数据模型

CREATE TABLE "business_hours" (
    "id" integer NOT NULL PRIMARY KEY,
    "day" varchar(16) NOT NULL,
    "open_time" time,
    "close_time" time
)

其中“日”仅限于代码中一周7天的选择(通过ORM) . 要测试某个企业是否在某一天关闭,它会检查open_time和close_time是否为NULL . 它通过中间表(多对多关系)与业务相关 .

有没有人对这个数据库方案有任何建议?关于它的一些事情对我来说似乎并不合适 .

5 回答

  • 9

    总的来说,我认为这没有错 . 除了...

    • 我会使用您的本机编程语言使用的任何编号系统(在其库中)将星期几存储为整数 . 这将减小数据库的大小并从代码中删除字符串比较 .

    • 我可能会将外键放在此表中的业务表中 . 这样你就不需要链接表了 .

    所以我想我会这样做:

    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
    )
    

    在我的业务逻辑中,我会强制执行每个"business" at least 的约束 . (至少因为Jon Skeet是对的,你可能想要休假时间 . )虽然您可能希望放松这个约束,只需在业务关闭的几天内停止"business hours" .

  • 20

    此架构未涵盖的一种情况是一天中的几个开放时段 . 例如,当地酒吧的营业时间为12:00-14:30和17:00-23:00 .

    也许剧院售票处可以进行日场表演和晚间表演 .

    此时,您需要决定同一天是否可以有多个条目,或者您是否需要在同一行中表示不同的小时数 .

    那个跨越午夜的开放时间怎么样?比如说酒吧营业时间为19:00-02:00 . 您不能只将开始和结束时间与您要测试的时间进行比较 .

  • 40

    它取决于您需要存储的内容以及实际数据的外观 .
    如果您需要能够确定业务是否在某个时间点开放,那么查询该方案可能有点尴尬 . 更重要的是,您是否需要迎合中午关闭?

    一些选择包括;

    • 一个类似你所拥有的计划,但可以选择在同一天拥有多个期间 . 它可以满足午休时间的需要,但是会让您查看给定的一天的开放时间,比如向用户展示,这会让您感到尴尬 .

    • 位图风格方法; "000000000111111110000000"代表9-5 . 这种方法的缺点是你必须选择一个特定的粒度,即整个小时或半小时,或者实际上是分钟 . 粒度越精细,人类就越难读取数据 . 您可以使用按位运算符将此值存储为单个数字而不是整数字符串,但同样会损害易读性 .

  • 8

    我了解到,如果您想让Google数据标记识别您的数据,您应该遵循以下准则:

    https://schema.org/openingHours

    http://schema.org/OpeningHoursSpecification包含"valid dates",这对某些企业非常有用 .

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

    没有主键你应该没事,除非你允许企业与联盟表共享相同的时间 - 有趣的是最终你将拥有有限数量的组合;我不确定会有多少:p

    在我的一个项目中,我使用了列:

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

    如果您想支持OpeningHoursSpecification,则需要添加validFrom和validThrough .

    时间范围的格式如下:hh:mm-hh:mm

    这是一个解析它的函数,如果将它们作为DB中的单独列保存,您也可以修改此函数以解析单个打开/关闭 .

    根据我的经验,我建议您在一天内允许多次,允许告诉他们当天是明确关闭,还是24小时或24/7开放 . 我曾经说过,如果数据库中缺少一天,那么业务当天就关闭了 .

    /**
     * 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

    可以考虑通过在月份/月/月中包含其他字段来考虑假期因素 . 一周中有一些小的子句“最后”可以是例如第4周或第5周,具体取决于年份 .

相关问题