use*_*000 76 database database-design
我目前正在尝试找出在数据库中存储业务小时数的最佳方法.
例如:
业务A有以下营业时间
目前我有一个类似于以下的数据模型
CREATE TABLE "business_hours" (
"id" integer NOT NULL PRIMARY KEY,
"day" varchar(16) NOT NULL,
"open_time" time,
"close_time" time
)
Run Code Online (Sandbox Code Playgroud)
其中"日"仅限于代码中一周7天的选择(通过ORM).要测试某个企业是否在某一天关闭,它会检查open_time和close_time是否为NULL.它通过中间表(多对多关系)与业务相关.
有没有人对这个数据库方案有任何建议?关于它的一些事情对我来说似乎并不合适.
Fra*_*ger 50
总的来说,我认为这没有错.除了...
我会使用您的本机编程语言使用的任何编号系统(在其库中)将星期几存储为整数.这将减少数据库的大小并从代码中删除字符串比较.
我可能会将外键放在此表中的业务表中.这样你就不需要链接表了.
所以我想我会这样做:
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
)
Run Code Online (Sandbox Code Playgroud)
在我的业务逻辑中,我会强制执行约束,即每个"业务" 至少有 7个"营业时间".(至少因为Jon Skeet是对的,你可能想要休假时间.)虽然你可能想要放松这个限制,只需在业务关闭的几天内停止"营业时间".
dav*_*don 22
此架构未涵盖的一种情况是一天中的几个开放时段.例如,当地酒吧的营业时间为12:00-14:30和17:00-23:00.
也许剧院售票处可以进行日场演出和晚间演出.
此时,您需要决定同一天是否可以有多个条目,或者是否需要在同一行中表示不同的小时数.
那个跨越午夜的开放时间怎么样?比如说酒吧营业时间为19:00-02:00.您不能只将开始和结束时间与您要测试的时间进行比较.
Fra*_*ans 10
它取决于您需要存储的内容以及实际数据的外观.
如果您需要能够确定业务是否在某个时间点开放,那么查询该方案可能有点尴尬.更重要的是,您是否需要迎合中午关闭?
一些选项包括;
我了解到,如果您想让Google数据标记识别您的数据,您应该遵循以下准则:
https://schema.org/openingHours
http://schema.org/OpeningHoursSpecification包含"有效日期",这对某些企业非常有用.
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;
}
Run Code Online (Sandbox Code Playgroud)
大多数结果对于给定的场景都可以正常工作,但如果您的经期持续多天,例如,它就不会那么有效。8:00 AM ~ 2:00 AM,那么我建议使用多时段设计。
{
id: 1,
day: 1,
periods: [
0: { open: 08:00, close: 00:00 }
]
},
{
id: 2,
day: 2,
periods: [
0: { open: 08:00, close: 00:00 }
1: { open: 00:00, close: 02:00 }
]
}
Run Code Online (Sandbox Code Playgroud)
day : 一周中的第几天,
如果没有句号,则表示休息