我计划为商店储存工作时间。我想知道工作时间字段的最佳建模方式是什么,这样我就可以非常高效地获得当前打开/关闭的店铺列表
要存储正常工作时间,您需要存储大量包含以下内容的记录:
- 车间整数
- DayOfWeek-整数(0-6)
- 开放时间
- 关门时间
例如,我假设每个商店在国庆节期间都减少了营业时间,或者工厂关闭,因此您还需要存储一些覆盖记录:
- 车间整数
- OverrideStartDate-日期
- 覆盖日期
- DayOfWeek-整数(0-6)
- AltOpenTime-时间
- 时间-时间
- 闭合-整数(0,1)
查找开放的店铺很简单,但您还需要检查是否有覆盖时间:
选择店铺
从过去几小时
其中OverrideStartDate<;=现在()
和覆盖数据>;=现在()
和DayOfWeek=工作日(现在())
如果有任何记录被退回,那么这些商店将轮流营业或关闭
这里可能有一些很好的SQL fu,但这将为您提供基础知识
编辑
我还没有测试过,但这会让你接近:
选择普通商店
从正常
左连接覆盖
正常情况下.Shop=Override.Shop
并且Normal.DayOfWeek=Override.DayOfWeek
现在()在Override.OverrideStartDate和Override.OverrideEndDate之间
其中Normal.DayOfWeek=工作日(NOW())
和((Override.Shop为NULL,TIME(NOW())介于Normal.OpenTime和Normal.CloseTime之间)
或(Override.Shop不为NULL,Override.Closed<;>;1和Override.AltOpenTime和Override.AltCloseTime之间的时间(NOW())
编辑
至于效率,它是有效的,因为您只需要对MySQL进行一次调用,如果MySQL跨越网络,这通常是一个瓶颈。您必须进行测试,看看这是否符合您的规范。如果不是,你可能会玩一些指数
编辑
测试。不是完整的测试,但是有些
mysql>;从“正常”中选择*;
+------+-----------+----------+-----------+
|商店|星期五|营业时间|关门时间|
+------+-----------+----------+-----------+
| 1 | 1 | 09:00:00 | 17:00:00 |
| 1 | 5 | 09:00:00 | 16:00:00 |
| 2 | 1 | 09:00:00 | 17:00:00 |
| 2 | 5 | 09:00:00 | 17:00:00 |
+------+-----------+----------+-----------+
一组4行(0.01秒)
mysql>;从覆盖中选择*;
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
|店铺| OverrideStartDate | OverrideEndDate |星期几|营业时间|营业时间|营业结束时间||
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
| 2 | 2010-12-01 | 2010-12-31 | 1 | 09:00:00 | 18:00:00 | 0 |
| 2 | 2010-12-01 | 2010-12-31 | 5 | 09:00:00 | 18:00:00 | 0 |
| 1 | 2010-12-01 | 2010-12-31 | 1 | 09:00:00 | 17:00:00 | 1 |
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
一组3行(0.00秒)
mysql>;设置@where=TIMESTAMP('2010-11-23 16:05');
查询正常,0行受影响(0.00秒)
mysql>;选择工作日(@where);
+--------------------+
|工作日(@where)|
+--------------------+
| 1 |
+--------------------+
一行一组(0.00秒)
mysql>;选择Normal.Shop FROM Normal LEFT在Normal.Shop=Override.Shop和Normal.DayOfWeek=Override.DayOfWeek和@WHERE之间连接Override.OverrideStartDate和Override.OverrideEndDate,其中Normal.DayOfWeek=WEEKDAY(@WHERE)和((Override.Shop为NULL,而时间(@WHERE)介于Normal.OpenTime和Normal.CloseTime)之间)或(Override.Shop不为NULL,Override.Closed<;>;1和Override.AltOpenTime和Override.AltCloseTime之间的时间(@where));
+------+
|商店|
+------+
| 1 |
| 2 |
+------+
一组2行(0.00秒)
mysql>;设置@where=TIMESTAMP('2010-11-23 17:05');
查询正常,0行受影响(0.00秒)
mysql>;选择Normal.Shop FROM Normal LEFT连接Normal.Shop=Override.Shop和Normal.DayOfWeek=Override.DayOfWeek和@WHERE介于Override.OverrideStartDate和Override.OverrideEndDate之间,其中Normal.DayOfWeek=WEEKDAY(@WHERE)和((Override.Shop为NULL,时间(@WHERE)介于Normal.OpenTime和Normal.CloseTime)之间)或(Override.Shop不为NULL,Override.Closed<;>;1和Override.AltOpenTime与Override.AltCloseTime之间的时间(@where));
空集(0.01秒)
mysql>;设置@where=TIMESTAMP('2010-12-25 16:05');
查询正常,0行受影响(0.00秒)
mysql>;选择Normal.Shop FROM Normal LEFT连接Normal.Shop=Override.Shop和Normal.DayOfWeek=Override.DayOfWeek和@WHERE介于Override.OverrideStartDate和Override.OverrideEndDate之间,其中Normal.DayOfWeek=WEEKDAY(@WHERE)和((Override.Shop为NULL,时间(@WHERE)介于Normal.OpenTime和Normal.CloseTime)之间)或(Override.Shop不为NULL,Override.Closed<;>;1和Override.AltOpenTime与Override.AltCloseTime之间的时间(@where));
+------+
|商店|
+------+
| 2 |
+------+
一行一组(0.00秒)
mysql>;设置@where=TIMESTAMP('2010-11-23 17:05');
查询正常,0行受影响(0.00秒)
mysql>;选择工作日(@where);
+--------------------+
|工作日(@where)|
+--------------------+
| 1 |
+--------------------+
一行一组(0.00秒)
mysql>;选择Normal.Shop FROM Normal LEFT连接Normal.Shop=Override.Shop和Normal.DayOfWeek=Override.DayOfWeek和@WHERE介于Override.OverrideStartDate和Override.OverrideEndDate之间,其中Normal.DayOfWeek=WEEKDAY(@WHERE)和((Override.Shop为NULL,时间(@WHERE)介于Normal.OpenTime和Normal.CloseTime)之间)或(Override.Shop不为NULL,Override.Closed<;>;1和Override.AltOpenTime与Override.AltCloseTime之间的时间(@where));
空集(0.00秒)