डेटटाइम स्टोर करने का पसंदीदा तरीका


18

हम कुछ तरीकों से दिनांक और समय की जानकारी संग्रहीत कर सकते हैं। डेटटाइम जानकारी संग्रहीत करने के लिए सबसे अच्छा तरीका क्या है?

2 अलग-अलग कॉलम या डेटाइम का उपयोग करके एक कॉलम में दिनांक और समय संग्रहीत करना ?

क्या आप बता सकते हैं कि दृष्टिकोण बेहतर क्यों है?

(संदर्भ के लिए MySQL डॉक्स से लिंक करें, प्रश्न सामान्य है, MySQL के लिए विशिष्ट नहीं है)
दिनांक और समय प्रकार: दिनांक और समय


3
यह काफी हद तक निर्भर करता है कि आप किस डेटाबेस सिस्टम का उपयोग कर रहे हैं। इसके लायक के लिए: ओरेकल ने इसे एक कॉलम (DATETIME डेटाटाइप के रूप में) के रूप में चुना, इस मामले में, उनके समर्थन में निर्मित निश्चित रूप से 2 कॉलम में उस जानकारी को NUMBER डेटाैटिस (यहां तक ​​कि आप केवल के रूप में संग्रहीत करने की तुलना में बेहतर होने जा रहा है) किसी दिए गए प्रश्न के लिए 1 भाग चाहिए ... दिनांक या समय)।
क्रिश जॉन्सटन

5
SQL सर्वर एक मामले के लिए जहां विभाजन को प्राथमिकता दी जा सकती है, वह तारीख तक समूहीकरण के लिए है। एक धारा कुल पर समग्र सूचकांक के लिए एक तरह से बिना इस्तेमाल किया जा करने में सक्षम हो जाएगा date,time के साथ group by dateलेकिन पर एक सूचकांक के लिए नहीं datetime के साथ group by cast(datetime as date)भले ही यह वांछित क्रम की आपूर्ति करेगी।
मार्टिन स्मिथ

1
ध्यान दें कि समय मानों पर किसी भी गणित को तिथि और समय-क्षेत्र जानने की आवश्यकता होती है - जैसे कि दो बार के बीच की दूरी उस दिन की डीएसटी घटना पर निर्भर करती है, कुछ दिनों में 23 या 25 घंटे होते हैं, और लीप सेकंड भी मौजूद होते हैं।
पीटरिस

जवाबों:


23

डेटा को एक ही कॉलम में संग्रहीत करना पसंदीदा तरीका है, क्योंकि वे अटूट रूप से जुड़े हुए हैं। समय का एक बिंदु जानकारी का एक टुकड़ा है, दो नहीं।

कई उत्पादों द्वारा "दृश्यों के पीछे" नियोजित दिनांक / समय डेटा को संग्रहीत करने का एक सामान्य तरीका है, इसे एक दशमलव मान में परिवर्तित करके, जहां "दिनांक" दशमलव मान का पूर्णांक भाग है, और "समय" आंशिक है मूल्य। तो, 1900-01-01 00:00:00 को 0.0 और सितंबर 20, 2016 9:34:00 को 42631.39861 के रूप में संग्रहीत किया जाता है। 4-0131 1900-01-01 के बाद के दिनों की संख्या है। .39861 आधी रात के बाद से गुजरे समय का हिस्सा है। ऐसा करने के लिए सीधे दशमलव प्रकार का उपयोग न करें, स्पष्ट तिथि / समय प्रकार का उपयोग करें; यहाँ मेरी बात सिर्फ एक दृष्टांत है।

डेटा को दो अलग-अलग स्तंभों में संग्रहीत करने का मतलब है कि आपको किसी भी समय दोनों कॉलम मानों को संयोजित करने की आवश्यकता होगी, यदि आप किसी दिए गए बिंदु को संग्रहीत मान से पहले या बाद में देखना चाहते हैं।

यदि आप मानों को अलग से संग्रहीत करते हैं, तो आप हमेशा "बग" में चलेंगे जो कि पता लगाना मुश्किल है। उदाहरण के लिए निम्नलिखित लें:

IF OBJECT_ID('tempdb..#DT') IS NOT NULL
DROP TABLE #DT;
CREATE TABLE #DT
(
    dt_value DATETIME NOT NULL
    , d_value DATE NOT NULL
    , t_value TIME(0) NOT NULL
);


DECLARE @d DATETIME = '2016-09-20 09:34:00';

INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);

SET @d = '2016-09-20 11:34:00';

INSERT INTO #DT (dt_value, d_value, t_value)
SELECT @d, CONVERT(DATE, @d), CONVERT(TIME(0), @d);

/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.dt_value >= '2016-07-01 11:00:00';

/* show all rows with a date after 2016-07-01 11:00 am */
SELECT *
FROM #DT dt
WHERE dt.d_value >= CONVERT(DATE, '2016-07-01')
    AND dt.t_value >= CONVERT(TIME(0), '11:00:00');

उपरोक्त कोड में, हम एक परीक्षण तालिका बना रहे हैं, इसे दो मूल्यों के साथ पॉप्युलेट कर रहे हैं, फिर उस डेटा के खिलाफ एक सरल क्वेरी का प्रदर्शन कर रहे हैं। पहला SELECTदोनों पंक्तियों को वापस करता है, हालांकि दूसरा SELECTकेवल एक पंक्ति देता है, जो वांछित परिणाम नहीं हो सकता है:

यहाँ छवि विवरण दर्ज करें

दिनांक / समय सीमा को फ़िल्टर करने का सही तरीका जहां मान असतत कॉलम में हैं, जैसा कि @ypercube द्वारा टिप्पणियों में बताया गया है, देखें:

WHERE dt.d_value > CONVERT(DATE, '2016-07-01') /* note there is no time component here */
    OR (
        dt.d_value = CONVERT(DATE, '2016-07-01') 
        AND dt.t_value >= CONVERT(TIME(0), '11:00:00')
    )

यदि आपको विश्लेषण उद्देश्यों के लिए अलग किए गए समय घटक की आवश्यकता है, तो आप मूल्य के समय भाग के लिए एक परिकलित, स्थायी, स्तंभ जोड़ने पर विचार कर सकते हैं:

ALTER TABLE #DT
ADD dt_value_time AS CONVERT(TIME(0), dt_value) PERSISTED;

SELECT *
FROM #dt;

यहाँ छवि विवरण दर्ज करें

इसके बाद बने कॉलम को समय-समय पर तेजी से हल करने आदि की अनुमति दी जा सकती है।

यदि आप प्रदर्शन उद्देश्यों के लिए दिनांक और समय को दो क्षेत्रों में विभाजित करने पर विचार कर रहे हैं, तो आपको महसूस करना चाहिए कि स्वरूपण क्लाइंट पर किया जाना चाहिए, न कि सर्वर पर।


11

मैं अन्य उत्तरों के लिए एक असहमति राय प्रदान करने जा रहा हूं।

यदि दिनांक और समय दोनों घटकों को एक साथ आवश्यक है यानी एक प्रविष्टि अमान्य है यदि इसमें एक नहीं है, लेकिन दूसरा नहीं है (या एक में NULL नहीं है, लेकिन दूसरे में नहीं है), तो इसे एक कॉलम में संग्रहीत करना अन्य कारणों में दिए गए कारणों से समझ में आता है जवाब।

हालांकि, यह मामला हो सकता है कि एक या दोनों घटक व्यक्तिगत रूप से वैकल्पिक हों। उस स्थिति में इसे एक कॉलम में संग्रहीत करना गलत होगा। ऐसा करने से आप मनमाने तरीके से NULL मानों का प्रतिनिधित्व करने के लिए बाध्य होंगे, जैसे समय 00:00:00 तक संग्रहीत करना।

यहां कुछ उदाहरण दिए गए हैं:

  • आप माइलेज टैक्स कटौती के लिए वाहन यात्रा रिकॉर्ड कर रहे हैं। यात्रा का सही समय जानना उपयोगी होगा, लेकिन यदि कोई कर्मचारी इसे नोट नहीं करता है और भूल गया है, तो तारीख अभी भी खुद को दर्ज करना चाहिए (आवश्यक तिथि, वैकल्पिक समय)।

  • आप यह पता लगाने के लिए एक सर्वेक्षण कर रहे हैं कि लोग अपने दोपहर के भोजन को किस समय खाते हैं, और आप प्रतिभागियों को अपने लंच के समय के नमूने के साथ एक फॉर्म पूरा करने के लिए कहते हैं, जिसमें तारीखें भी शामिल हैं। कुछ लोग तारीख भरने की जहमत नहीं उठाते हैं, और आप डेटा को छोड़ना नहीं चाहते क्योंकि यह वह समय होता है जब आप वास्तव में परवाह करते हैं (वैकल्पिक तिथि, आवश्यक समय)।

वैकल्पिक दृष्टिकोण के लिए यह संबंधित प्रश्न देखें ।


में आरएफसी 3339 रिकॉर्डिंग के लिए एक सम्मेलन "अज्ञात स्थानीय ऑफसेट" नहीं है। मुझे नहीं लगता कि यह "अज्ञात समय" के उपयोग के मामले को काफी कवर करता है, लेकिन यह करीब है। अगले खंड "अयोग्य स्थानीय समय" और भी करीब है, लेकिन फिर से यह काफी पर्याप्त नहीं है।
जीनोरमा

हां, मैं इस समय इस वजह से अपने स्कीमा को रिफलेक्ट करने के बैरल को घूर रहा हूं। कार किराए पर लेने की स्थिति लें। किराये की कंपनी से कार लेने के लिए - कंपनी को खोलने की आवश्यकता है; इसलिए आप पिक के लिए एक तिथि और समय निर्दिष्ट करते हैं। हालाँकि, कई में की-बॉक्स होते हैं; तो आप घंटे के बाद छोड़ देते हैं। इसलिए यदि रविवार को स्थान बंद है; ड्रॉप-ऑफ की तारीख है; लेकिन एक समय नहीं। 0 मान संग्रहीत करना (जैसे 12am) काम नहीं करेगा क्योंकि कुछ स्थान आधी रात तक खुले रहते हैं, जो अन्य स्थितियों में एक मान्य मूल्य है।
रीसस

5

मैं हमेशा एक ही कॉलम के रूप में संग्रहीत करना पसंद करूंगा जब तक कि कुछ विशिष्ट व्यवसाय / आवेदन की मांग न हो। नीचे मेरे बिंदु हैं -

  • टाइमस्टैम्प से समय निकालना कोई समस्या नहीं है
  • अगर हम दोनों को एक साथ स्टोर कर सकते हैं तो समय के लिए अतिरिक्त कॉलम क्यों जोड़ें
  • जब भी आप क्वेरी कर रहे हों, हर बार तिथि और समय जोड़ने से बचें।

1
@a_horse_with_no_name का यहाँ एक बिंदु है। मुझे लगता है कि "डेटाटेस्टैम्प से टाइमस्टैम्प को निकालना कोई समस्या नहीं है" को फिर से परिभाषित किया जाना चाहिए क्योंकि " टाइमस्टैम्प से समय निकालना एक समस्या नहीं है" । "टाइमस्टैम्प" का अर्थ आमतौर पर तारीख और समय (और आमतौर पर टाइमज़ोन) दोनों होता है।
ypercube y

हाँ, सहमत @ ypercubeᵀᴹ। टाइमस्टैम्प का मतलब आमतौर पर तारीख और समय दोनों होता है। मैंने स्पष्ट रूप से DateTimeStamp शब्द का उल्लेख किया है, इसलिए कोई भी समझ सकता है कि हम तारीख और समय दोनों के बारे में बात कर रहे हैं। लेकिन आप भी सही हैं। उत्तर को संशोधित किया।
अश्विनी मोहन

3

SQL सर्वर में डेटाटाइम को एक फ़ील्ड के रूप में संग्रहीत करना सबसे अच्छा है। यदि आप डेटाइम कॉलम पर एक इंडेक्स बनाते हैं तो इसे डेट सर्च के रूप में और डेटटाइम सर्च के रूप में उपयोग किया जा सकता है। इसलिए यदि आपको विशिष्ट तिथि के लिए मौजूद सभी रिकॉर्डों को सीमित करने की आवश्यकता है, तो आप अभी भी कुछ विशेष करने के बिना सूचकांक का उपयोग कर सकते हैं। यदि आपको समय भाग के लिए क्वेरी करने की आवश्यकता है, तो आप एक ही इंडेक्स का उपयोग नहीं कर पाएंगे और इसलिए यदि आपके पास कोई व्यावसायिक मामला है, जहाँ आप दिन के समय की तुलना में डेटाइम से अधिक देखभाल करते हैं, तो आपको इसे अलग से स्टोर करना चाहिए जैसा कि आपको बनाने की आवश्यकता होगी इस पर एक सूचकांक और प्रदर्शन में सुधार।


1

वास्तव में, यह अफ़सोस की बात है कि इसके लिए कोई मानक क्रॉस-डीबीएमएस प्रकार नहीं है (जैसे INT और VARCHAR पूर्णांक और स्ट्रिंग के लिए हैं)। 2 क्रॉस-डेटाबेस दृष्टिकोण जो मुझे अब तक मिले हैं, डेटाटाइम मानों को आईएसओ 8601 (अधिक सुविधाजनक, मानव-पठनीय) मानक के अनुसार स्वरूपित करने के लिए VARCHAR / CHAR कॉलम का उपयोग कर रहे हैं और POSIX टाइमस्टैम्प (संग्रहीत अधिक संग्रहीत) के लिए BIGINT का उपयोग कर रहे हैं कुशलतापूर्वक, तेज, गणितीय रूप से हेरफेर करने में आसान)।


2
हाँ वहाँ है: timestampकि SQL मानक क्या परिभाषित करता है। स्ट्रिंग्स के रूप में टाइमस्टैम्प्स को स्टोर करना एक बहुत बुरी सलाह है
a_horse_with_no_name

0

सामान का एक गुच्छा पढ़ने के बाद, BIGINT में UTC यूनिक्स का समय इष्टतम समाधान लगता है। यदि आवश्यक हो तो समय क्षेत्र भंडारण के लिए VARCHAR में TZDB timesone आईडी। कुछ तर्क:

  1. TIMESTAMP और DATIMEIME पृष्ठभूमि में बनावटी रूपांतरणों का एक समूह बनाते हैं जो जटिल लगते हैं और स्पष्ट नहीं होते हैं। सर्वर स्थानीय समय से यूटीसी या सर्वर समय और पीछे, कभी-कभी, या नहीं पर स्विच करता है। हर समारोह के लिए छिपे हुए ओवरहेड का एक गुच्छा।

  2. BIGINT (8kb) xxxxxx.xxxxxx फॉर्मेट स्टोरेज के लिए DECIMAL की तुलना में कम से कम प्रकाश या हल्का है, जो कि MySQL द्वारा दो INT + के रूप में व्यावहारिक रूप से संग्रहीत है । और यह सदियों आगे की दुकान करने के लिए पर्याप्त है।

  3. बहुत अधिक सभी प्रमुख प्रोग्रामिंग भाषाओं में यूनिक्स समय के साथ काम करने के लिए मानक कार्यों के पुस्तकालय हैं।

  4. BIGINT के साथ गणित का संचालन किसी भी हार्डवेयर पर किसी भी चीज़ की तुलना में बहुत तेज़ या तेज़ होना चाहिए।

बेशक उपरोक्त सभी बड़ी, अंतर्राष्ट्रीय परियोजनाओं के लिए प्रासंगिक हैं। कुछ छोटे के लिए, चुने हुए ढांचे के डिफ़ॉल्ट प्रारूप के साथ जाना काफी अच्छा लगता है।


2
" पृष्ठभूमि में बनावटी रूपांतरणों का एक समूह है जो लगता है ... स्पष्ट नहीं है " - आप किस डीबीएमएस के बारे में बात कर रहे हैं? किसी timestampकॉलम के लिए ("नौटंकी रूपांतरण" होता है) (डेटाबेस लेयर पर) और इसके लिए timestamp with time zoneअच्छी तरह से प्रलेखित और मैनुअल में समझाया गया है (कम से कम Oracle और Postgres के लिए)
a_horse_with_no_name

1
"बहुत अधिक सभी प्रमुख प्रोग्रामिंग भाषाओं में यूनिक्स समय के साथ काम करने के लिए मानक कार्यों के पुस्तकालय हैं।" और फिर भी आप तारीखों, डेटाटाइम और टाइमस्टैम्प के बारे में सभी पुस्तकालयों और कार्यों को फेंक देते हैं जो SQL / DBMS के पास है, आपकी पसंद के साथ bigint ...
ypercubeᵀᴹ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.