我打算存储商店的工作时间。我想知道什么可能是工作时间领域的最佳建模,以便我可以非常有效地获得当前开放/关闭商店的列表。存储工作时间和高效查询的最佳方式
27
A
回答
44
要存储的正常运行时间,你将需要存储多个含有记录:
- 店 - INTEGER
- DAYOFWEEK - INTEGER( 0-6)
- OpenTime - TIME
- CloseTim Ë - TIME
我假设例如在节假日每家店铺已经减少小时,或有工厂停工,所以你也需要存储一些替代记录:
- 店 - INTEGER
- OverrideStartDate - DATE
- OverrideEndDate - DATE
- DAYOFWEEK - INTEGER(0-6)
- AltOpenTime - TIME
- AltCloseTime - TIME
- 封闭 - 整数(0,1)
找到空位的商店是微不足道的,但你还需要检查是否有越权小时:
SELECT Shop
FROM OverrideHours
WHERE OverrideStartDate <= NOW()
AND OverrideEndDate >= NOW()
AND DayOfWeek = WEEKDAY(NOW())
如果有是否有任何记录被返回,这些商店有交替时间或关闭。
可能有一些很好的SQL-fu可以在这里做,但是这给了你基本的东西。
编辑
我没有测试过这一点,但是这应该让你接近:
SELECT Normal.Shop
FROM Normal
LEFT JOIN Override
ON Normal.Shop = Override.Shop
AND Normal.DayOfWeek = Override.DayOfWeek
AND NOW() BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate
WHERE Normal.DayOfWeek = WEEKDAY(NOW())
AND ((Override.Shop IS NULL AND TIME(NOW()) BETWEEN Normal.OpenTime AND Normal.CloseTime)
OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(NOW()) BETWEEN Override.AltOpenTime AND Override.AltCloseTime))
编辑
至于效率,它是在这个意义上是有效的你只需要打一个电话给MySQL,如果它是通过网络的话,这通常是一个瓶颈。您必须测试并查看这是否符合您的规格。如果没有,你可能会玩一些指数。
编辑
测试。不完整的测试,但一些。
mysql> select * from Normal;
+------+-----------+----------+-----------+
| Shop | DayOfWeek | OpenTime | CloseTime |
+------+-----------+----------+-----------+
| 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 rows in set (0.01 sec)
mysql> select * from Override;
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
| Shop | OverrideStartDate | OverrideEndDate | DayOfWeek | AltOpenTime | AltCloseTime | Closed |
+------+-------------------+-----------------+-----------+-------------+--------------+--------+
| 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 rows in set (0.00 sec)
mysql> SET @whenever = TIMESTAMP('2010-11-23 16:05');
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT WEEKDAY(@whenever);
+--------------------+
| WEEKDAY(@whenever) |
+--------------------+
| 1 |
+--------------------+
1 row in set (0.00 sec)
mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
+------+
| Shop |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
mysql> SET @whenever = TIMESTAMP('2010-11-23 17:05');
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
Empty set (0.01 sec)
mysql> SET @whenever = TIMESTAMP('2010-12-25 16:05');
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
+------+
| Shop |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
mysql> SET @whenever = TIMESTAMP('2010-11-23 17:05');
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT WEEKDAY(@whenever);
+--------------------+
| WEEKDAY(@whenever) |
+--------------------+
| 1 |
+--------------------+
1 row in set (0.00 sec)
mysql> SELECT Normal.Shop FROM Normal LEFT JOIN Override ON Normal.Shop = Override.Shop AND Normal.DayOfWeek = Override.DayOfWeek AND @whenever BETWEEN Override.OverrideStartDate AND Override.OverrideEndDate WHERE Normal.DayOfWeek = WEEKDAY(@whenever) AND ((Override.Shop IS NULL AND TIME(@whenever) BETWEEN Normal.OpenTime AND Normal.CloseTime) OR (Override.Shop IS NOT NULL AND Override.Closed <> 1 AND TIME(@whenever) BETWEEN Override.AltOpenTime AND Override.AltCloseTime));
Empty set (0.00 sec)
8
让我们考虑每周的开放时间都是一样的。那么,关于下表:
- shop_id - INTEGER(或车间的任何唯一标识符)
- WEEK_DAY - INTEGER(0 =周一 - 6 =周日)
- opens_at - 时间(使用本地时区)
- closes_at - 时间(使用本地时区)
做一个表,通过shop_id
标识的商店,然后插入的开放时间,即:
- 1,0,8点,17:00
- ...
- 1,5,8点,12:00
- 2,0:30,7:30,12:30
- 2,0,13:30,17:30
- 2,1:30,7:30,12:30
- 2,1,13:30,17:30
- ...
,然后选择:
SELECT shop_id
FROM opening_hours
WHERE WEEKDAY(NOW()) = week_day
AND TIME(NOW()) BETWEEN opens_at AND closes_at
相关问题
- 1. 存储“时间”值的最佳方法
- 2. 在Mongo中存储/查询`last_read`的最佳方式是什么?
- 3. 最佳方式查询
- 4. 存储查找值的最佳方法
- 5. 存储配置的最佳方式
- 6. iPad - 存储数据的最佳方式
- 7. 存储数据的最佳方式
- 8. 存储数据的最佳方式
- 9. 存储输入值的最佳方式
- 10. mysql更高效的查询方式
- 11. 在SQL表中存储课程的最高效方式
- 12. 索引/存储用于搜索/检索的代码(脚本,查询)的最佳高效方法是什么?
- 13. RDF三元组的高效存储和查询
- 14. 最佳方式存储上传图像
- 15. 在python中存储状态空间的最佳方式
- 16. 高效的方式基于时间
- 17. 查询Firebase的最有效方式iOS
- 18. 存储调查数据的最佳方式?
- 19. 存储一周时间的最佳方法
- 20. 什么是保存用户名和高分的最佳方式
- 21. 最佳方式加入此查询
- 22. 最佳方式构建SQL查询
- 23. 什么是跨浏览器最小高度的最佳和有效的方式?
- 24. 效率内存和CPU使用率的最佳方式
- 25. 在ElasticSearch中保存用户搜索查询的最佳方式?
- 26. 什么是存储临时数据的最佳方式?
- 27. 排除查询集中的查询集的最佳方式
- 28. 将日期/时间存储到核心数据中的最佳方式
- 29. 在MySQL中存储时间序列的最佳方式是什么?
- 30. 什么是在MySQL中存储持续时间的最佳方式
很好的回答!快速提问:建议在“Shop”,“DayOfWeek”,“OpenTime”和“CloseTime”上添加索引吗? – RabidFire 2010-12-31 06:26:13
@RabidFire,请参阅http://stackoverflow.com/questions/3049283/mysql-indexes-what-are-the-best-practises的答案。如果您要查找的主要效率是查询(而不是插入),那么向WHERE或JOIN ON中使用的任何字段添加索引应加快搜索速度。你必须测试一下,看哪一个是最有效的。 – 2011-01-04 17:35:20
@RobertGowland如果晚上bussinsess在下午5点开门,第二天凌晨3点关门呢? – Antoniossss 2017-09-08 11:08:19