我打算存儲商店的工作時間。我想知道什麼可能是工作時間領域的最佳建模,以便我可以非常有效地獲得當前開放/關閉商店的列表。存儲工作時間和高效查詢的最佳方式
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