Mam zamiar przechowywać godziny pracy sklepów. Zastanawiam się, jakie może być najlepsze modelowanie pola czasu pracy, aby w bardzo wydajny sposób uzyskać listę otwartych/zamkniętych sklepów.Najlepszy sposób na przechowywanie godzin pracy i wydajne wysyłanie zapytań.
Odpowiedz
Aby zapisać normalnych godzin eksploatacji, trzeba by zapisać liczbę rekordów zawierających:
- Shop - INTEGER
- DzienTygodnia - INTEGER (0-6)
- OpenTime - CZAS
- CloseTim e - TIME
zakładam na przykład, że każdy sklep skrócenie czasu podczas świąt narodowych lub ma przestojów roślin, więc trzeba także przechowywać niektóre zapisy ręczne:
- sklep - Integer
- OverrideStartDate - DATA
- OverrideEndDate - DATA
- DzienTygodnia - INTEGER (0-6)
- AltOpenTime - TIME
- AltCloseTime - TIME
- Zamknięty - INTEGER (0, 1)
Aby znaleźć otwarte sklepów jest trywialne, ale trzeba także sprawdzić, czy istnieją godzin ręczne:
SELECT Shop
FROM OverrideHours
WHERE OverrideStartDate <= NOW()
AND OverrideEndDate >= NOW()
AND DayOfWeek = WEEKDAY(NOW())
Jeśli istnieje są wszelkie rekordy zwrócone, te sklepy mają alternatywne godziny lub są zamknięte.
Może być trochę fajnego SQL-fu, który możesz tutaj zrobić, ale to daje podstawy.
EDIT
Nie testowałem tego, ale to powinno się zamknąć:
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))
EDIT
Jeśli chodzi o wydajność, to jest skuteczne w tym sensie, że musisz tylko wykonać jedno połączenie z MySQL, które często jest wąskim gardłem, jeśli jest w sieci. Będziesz musiał sprawdzić i sprawdzić, czy spełnia on twoje wymagania. Jeśli nie, możesz grać z niektórymi indeksami.
EDIT
Testing. Niezupełne testy, ale niektóre.
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)
Rozważmy, że wszystkie godziny otwarcia są takie same co tydzień. Więc co z poniższej tabeli:
- shop_id - INTEGER (lub dowolnym unikalnym identyfikatorem sklepu)
- WEEK_DAY - INTEGER (0 = poniedziałek - 6 = niedziela)
- opens_at - TIME (użyj strefę czasową)
- closes_at - TIME (użyj strefę czasową)
Zrób stół dla sklepów wskazanych przez shop_id
a następnie włóż godziny otwarcia, tj:
- 1, 0, 08:00, 17:00
- ...
- 1, 5, 08:00, 12:00
- 2, 0, 07:30, 12:30
- 2, 0, 13:30, 17:30
- 2, 1, 7:30, 12:30
- 2, 1, 13:30, 17:30
- ...
a następnie wybierz:
SELECT shop_id
FROM opening_hours
WHERE WEEKDAY(NOW()) = week_day
AND TIME(NOW()) BETWEEN opens_at AND closes_at
- 1. Przechowywanie i wysyłanie zapytań do JSON z bazy danych
- 2. Najlepszy sposób na przechowywanie danych w BoltDB
- 3. Najlepszy sposób na przechowywanie uprawnień użytkownika?
- 4. Najlepszy sposób na przechowywanie obrazów w iOS
- 5. Jaki jest najlepszy sposób na przechowywanie i pobieranie wielowymiarowych NSMutableArrays?
- 6. Jakie bezpłatne/płatne interfejsy API wyszukiwania pozwalają na programowe wysyłanie zapytań i buforowanie/przechowywanie wynikowych danych?
- 7. Najlepszy sposób na przechowywanie "dodatkowych" danych użytkownika w MySQL?
- 8. Django - Obiekty dla godzin pracy
- 9. Najlepszy sposób na przechowywanie uporządkowanych list w bazie danych?
- 10. Najlepszy sposób na przechowywanie listy obiektów java w Redis
- 11. Najlepszy sposób na przechowywanie informacji o podatku obrotowym
- 12. Najlepszy sposób na przechowywanie haseł w bazie danych MySQL
- 13. Najlepszy sposób na przechowywanie tablicy w bazie danych MySQL?
- 14. Najlepszy sposób na przechowywanie danych hierarchicznych w hbase
- 15. Najlepszy sposób na przechowywanie klucza => tablica wartości w JavaScript?
- 16. Najlepszy sposób na przechowywanie wielu flag w bazie danych
- 17. Najlepszy sposób na wykonywanie długich zapytań DB w klasycznej ASP?
- 18. Najlepszy sposób monitorowania zakończenia pracy Sidekiq?
- 19. Obliczanie terminu za pomocą godzin pracy i świąt
- 20. Śledzenie godzin pracy za pomocą git
- 21. Najlepszy sposób na przechowywanie danych serii czasowej z dużym napisem i wysoką agregacją. (~ 1 miliard punktów)
- 22. Najlepszy sposób na przechowywanie czasu (tylko data i godzina) w bazie danych
- 23. Najlepszy sposób na przechowywanie nazwy użytkownika i hasła bez bazy danych
- 24. Najlepszy sposób na TDD i CSLA
- 25. Szybkie i wydajne obliczenia na tablicach
- 26. Przechowywanie zapytań SQL w pliku konfiguracyjnym?
- 27. Jaki jest najlepszy sposób pracy z akka od nodejs
- 28. Jaki jest najlepszy sposób uzyskania ostatnich 24 godzin w wyniku T-SQL?
- 29. Najlepszy sposób, aby dostać will_paginate pracy z Ajax
- 30. Jaki jest najlepszy sposób pracy z uprawnieniami w Angular 4?
Świetna odpowiedź! Szybkie pytanie: Czy wskazane byłoby umieszczanie indeksów w 'Shop',' DayOfWeek', 'OpenTime' ORAZ' CloseTime'? – RabidFire
@RabidFire, zobacz odpowiedzi na http://stackoverflow.com/questions/3049283/mysql-indexes-what-are-the-best-practises. Jeśli podstawowa wydajność, której szukasz, to zapytanie (na przykład w przeciwieństwie do wstawiania), dodanie indeksu do dowolnego pola użytego w WHERE lub JOIN ON powinno przyspieszyć wyszukiwanie.Będziesz musiał sprawdzić, które z nich są najbardziej skuteczne. –
@RobertGowland A co, jeśli nocny bussinsess otworzy się o 17:00 i zamknie o 3 rano następnego dnia? – Antoniossss