2010-12-16 7 views
27

मैं दुकानों के लिए कामकाजी घंटों को स्टोर करने की योजना बना रहा हूं। मैं सोच रहा हूं कि कामकाजी घंटों के क्षेत्र के लिए सबसे अच्छा मॉडलिंग क्या हो सकता है ताकि मैं वर्तमान क्षण में खुली/बंद दुकानों की सूची बहुत कुशल तरीके से प्राप्त कर सकूं।कामकाजी घंटों को स्टोर करने और इसे कुशलता से पूछने का सबसे अच्छा तरीका

उत्तर

44

सामान्य ऑपरेशन घंटे की दुकान के लिए, आपको युक्त रिकॉर्ड के एक नंबर स्टोर करने के लिए की आवश्यकता होगी:

  • दुकान - पूर्णांक
  • सप्ताह का दिन - पूर्णांक (0-6)
  • ओपनटाइम - समय
  • CloseTim ई - समय

मैं उदाहरण के लिए मान लेते हैं कि प्रत्येक दुकान राष्ट्रीय छुट्टियों के दौरान घंटे कम हो गया है, या है संयंत्र शटडाउन, तो आप भी कुछ ओवरराइड रिकॉर्ड की दुकान करने की आवश्यकता होगी:

  • दुकान - पूर्णांक
  • OverrideStartDate - DATE
  • OverrideEndDate - DATE
  • सप्ताह का दिन - पूर्णांक (0-6)
  • AltOpenTime - समय
  • AltCloseTime - समय
  • बंद - पूर्णांक (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) 
+0

शानदार उत्तर! त्वरित प्रश्न: क्या 'दुकान', 'डेऑफवेक', 'ओपनटाइम' और 'क्लोजटाइम' पर इंडेक्स रखने की सलाह दी जाएगी? – RabidFire

+1

@ रैबिडफायर, http://stackoverflow.com/questions/3049283/mysql-indexes-what-are-the-best-practises के उत्तरों को देखें। यदि आप जिस प्राथमिक दक्षता की तलाश में हैं, वह पूछताछ कर रहा है (उदाहरण के लिए सम्मिलन के विपरीत), फिर किसी भी क्षेत्र में किसी भी फ़ील्ड में एक इंडेक्स जोड़ना या जॉइन ऑन में खोज को तेज करना चाहिए।आपको यह देखने के लिए परीक्षण करना होगा कि कौन सा सबसे प्रभावी है। –

+0

@RobertGowland और क्या होगा अगर रात bussinsess 5 पीएम पर खुलता है और अगले दिन 3AM पर क्लॉस? – Antoniossss

8

मान लें कि सभी शुरुआती घंटे हर सप्ताह समान होते हैं। तो क्या निम्न तालिका के बारे में:

  • shop_id - पूर्णांक (या दुकान के किसी भी अद्वितीय पहचानकर्ता)
  • WEEK_DAY - पूर्णांक (0 = सोमवार - 6 = रविवार)
  • opens_at - समय (आपके स्थानीय समय क्षेत्र का उपयोग करें)
  • closes_at - समय (आपके स्थानीय समय क्षेत्र का उपयोग करें)

shop_id द्वारा की पहचान की दुकानों के लिए एक मेज करें और फिर खुलने का समय डालें, अर्थात्:

  • 1, 0, 8:00, शुक्रवार 17:00
  • ...
  • 1, 5, 8:00, 12:00
  • 2, 0, 7:30, 12:30
  • 2, 0, 13:30, 17:30
  • 2, 1, 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 
संबंधित मुद्दे