PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL डेटाबेस में मुझे कौन सा टाइमस्टैम्प प्रकार चुनना चाहिए?

सबसे पहले, PostgreSQL का टाइम हैंडलिंग और अंकगणित शानदार है और सामान्य मामले में विकल्प 3 ठीक है। हालांकि, यह समय और समय क्षेत्र का अधूरा दृश्य है और इसे पूरक बनाया जा सकता है:

  1. उपयोगकर्ता के समय क्षेत्र का नाम उपयोगकर्ता वरीयता के रूप में संग्रहीत करें (उदा. America/Los_Angeles , नहीं -0700 )।
  2. उपयोगकर्ता ईवेंट/समय डेटा को उनके संदर्भ के फ्रेम में स्थानीय रूप से सबमिट करें (संभवतः UTC से ऑफसेट, जैसे -0700 )।
  3. आवेदन में, समय को UTC में बदलें और एक TIMESTAMP WITH TIME ZONE . का उपयोग करके संग्रहीत किया जाता है कॉलम।
  4. उपयोगकर्ता के समय क्षेत्र में वापसी समय अनुरोध स्थानीय (यानी UTC से रूपांतरित करें) करने के लिए America/Los_Angeles )।
  5. अपने डेटाबेस का timezoneसेट करें करने के लिए UTC

यह विकल्प हमेशा काम नहीं करता है क्योंकि उपयोगकर्ता का समय क्षेत्र प्राप्त करना कठिन हो सकता है और इसलिए हेज सलाह TIMESTAMP WITH TIME ZONE का उपयोग करें हल्के अनुप्रयोगों के लिए। उस ने कहा, मैं इस विकल्प 4 के कुछ पृष्ठभूमि पहलुओं को और अधिक विस्तार से समझाता हूं।

विकल्प 3 की तरह, WITH TIME ZONE . का कारण ऐसा इसलिए है क्योंकि जिस समय कुछ हुआ वह पूर्ण . है न भूल सकने वाला लम्हा। WITHOUT TIME ZONE एक रिश्तेदार . पैदा करता है समय क्षेत्र। कभी भी, कभी भी, कभी भी निरपेक्ष और सापेक्ष TIMESTAMP को न मिलाएं।

प्रोग्रामेटिक और निरंतरता के दृष्टिकोण से, सुनिश्चित करें कि सभी गणनाएं समय क्षेत्र के रूप में UTC का उपयोग करके की गई हैं। यह एक PostgreSQL आवश्यकता नहीं है, लेकिन यह अन्य प्रोग्रामिंग भाषाओं या वातावरण के साथ एकीकृत करते समय मदद करता है। CHECK सेट करना कॉलम पर यह सुनिश्चित करने के लिए कि टाइम स्टैम्प कॉलम में लिखने का समय क्षेत्र ऑफसेट है 0 एक रक्षात्मक स्थिति है जो बग के कुछ वर्गों को रोकती है (उदाहरण के लिए एक स्क्रिप्ट एक फ़ाइल में डेटा डंप करती है और कुछ और एक लेक्सिकल सॉर्ट का उपयोग करके समय डेटा को सॉर्ट करता है)। फिर से, PostgreSQL को तारीख की गणना सही ढंग से करने या समय क्षेत्रों के बीच परिवर्तित करने की आवश्यकता नहीं है (यानी PostgreSQL किन्हीं दो मनमाने समय क्षेत्रों के बीच समय को परिवर्तित करने में बहुत माहिर है)। यह सुनिश्चित करने के लिए कि डेटाबेस में जाने वाला डेटा शून्य के ऑफसेट के साथ संग्रहीत है:

CREATE TABLE my_tbl (
  my_timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
  CHECK(EXTRACT(TIMEZONE FROM my_timestamp) = '0')
);
test=> SET timezone = 'America/Los_Angeles';
SET
test=> INSERT INTO my_tbl (my_timestamp) VALUES (NOW());
ERROR:  new row for relation "my_tbl" violates check constraint "my_tbl_my_timestamp_check"
test=> SET timezone = 'UTC';
SET
test=> INSERT INTO my_tbl (my_timestamp) VALUES (NOW());
INSERT 0 1

यह 100% सही नहीं है, लेकिन यह एक मजबूत पर्याप्त एंटी-फुटशूटिंग उपाय प्रदान करता है जो सुनिश्चित करता है कि डेटा पहले से ही यूटीसी में परिवर्तित हो गया है। इसे कैसे किया जाए, इस पर बहुत सारी राय है, लेकिन यह मेरे अनुभव से व्यवहार में सबसे अच्छा लगता है।

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

-- Make sure we're all working off of the same local time zone
test=> SET timezone = 'America/Los_Angeles';
SET
test=> SELECT NOW();
              now              
-------------------------------
 2011-05-27 15:47:58.138995-07
(1 row)

test=> SELECT NOW() AT TIME ZONE 'UTC';
          timezone          
----------------------------
 2011-05-27 22:48:02.235541
(1 row)

ध्यान दें कि AT TIME ZONE 'UTC' समय क्षेत्र की जानकारी छीन लेता है और एक सापेक्ष TIMESTAMP WITHOUT TIME ZONE बनाता है अपने लक्ष्य के संदर्भ के फ्रेम का उपयोग करना (UTC )।

अपूर्ण TIMESTAMP WITHOUT TIME ZONE . में कनवर्ट करते समय एक TIMESTAMP WITH TIME ZONE , अनुपलब्ध समय क्षेत्र आपके कनेक्शन से विरासत में मिला है:

test=> SET timezone = 'America/Los_Angeles';
SET
test=> SELECT EXTRACT(TIMEZONE_HOUR FROM NOW());
 date_part 
-----------
        -7
(1 row)
test=> SELECT EXTRACT(TIMEZONE_HOUR FROM TIMESTAMP WITH TIME ZONE '2011-05-27 22:48:02.235541');
 date_part 
-----------
        -7
(1 row)

-- Now change to UTC    
test=> SET timezone = 'UTC';
SET
-- Create an absolute time with timezone offset:
test=> SELECT NOW();
              now              
-------------------------------
 2011-05-27 22:48:40.540119+00
(1 row)

-- Creates a relative time in a given frame of reference (i.e. no offset)
test=> SELECT NOW() AT TIME ZONE 'UTC';
          timezone          
----------------------------
 2011-05-27 22:48:49.444446
(1 row)

test=> SELECT EXTRACT(TIMEZONE_HOUR FROM NOW());
 date_part 
-----------
         0
(1 row)

test=> SELECT EXTRACT(TIMEZONE_HOUR FROM TIMESTAMP WITH TIME ZONE '2011-05-27 22:48:02.235541');
 date_part 
-----------
         0
(1 row)

निचला रेखा:

  • उपयोगकर्ता के समय क्षेत्र को नामित लेबल के रूप में संग्रहीत करें (उदा. America/Los_Angeles ) और यूटीसी से ऑफसेट नहीं (उदा. -0700 )
  • सब कुछ के लिए UTC का उपयोग करें जब तक कि गैर-शून्य ऑफ़सेट स्टोर करने का कोई अनिवार्य कारण न हो
  • सभी गैर-शून्य UTC बार को इनपुट त्रुटि के रूप में मानें
  • सापेक्ष और पूर्ण टाइमस्टैम्प को कभी भी मिक्स एंड मैच न करें
  • UTC का भी उपयोग करें timezone . के रूप में डेटाबेस में यदि संभव हो तो

रैंडम प्रोग्रामिंग भाषा नोट:पायथन का datetime डेटा प्रकार निरपेक्ष बनाम सापेक्ष समय के बीच अंतर को बनाए रखने में बहुत अच्छा है (हालांकि पहली बार में निराशा होती है जब तक कि आप इसे PyTZ जैसी लाइब्रेरी के साथ पूरक नहीं करते)।

संपादित करें

मैं सापेक्ष बनाम निरपेक्ष के बीच के अंतर को थोड़ा और स्पष्ट करता हूं।

किसी घटना को रिकॉर्ड करने के लिए निरपेक्ष समय का उपयोग किया जाता है। उदाहरण:"उपयोगकर्ता 123 लॉग इन" या "एक स्नातक समारोह 2011-05-28 दोपहर 2 बजे पीएसटी से शुरू होता है।" आपके स्थानीय समय क्षेत्र के बावजूद, यदि आप उस स्थान पर टेलीपोर्ट कर सकते हैं जहां घटना हुई है, तो आप घटना को होते हुए देख सकते हैं। डेटाबेस में अधिकांश समय डेटा निरपेक्ष होता है (और इसलिए TIMESTAMP WITH TIME ZONE होना चाहिए। , आदर्श रूप से एक +0 ऑफ़सेट और विशेष समयक्षेत्र को नियंत्रित करने वाले नियमों का प्रतिनिधित्व करने वाला एक टेक्स्ट लेबल - ऑफ़सेट नहीं)।

एक सापेक्ष घटना अभी तक निर्धारित समय क्षेत्र के परिप्रेक्ष्य से किसी चीज़ के समय को रिकॉर्ड या शेड्यूल करना होगा। उदाहरण:"हमारे व्यवसाय के दरवाजे सुबह 8 बजे खुलते हैं और रात 9 बजे बंद हो जाते हैं", "चलो हर सोमवार को सुबह 7 बजे साप्ताहिक नाश्ते की बैठक के लिए मिलते हैं," या "हर हैलोवीन रात 8 बजे।" सामान्य तौर पर, घटनाओं के लिए एक टेम्पलेट या कारखाने में सापेक्ष समय का उपयोग किया जाता है, और लगभग हर चीज के लिए पूर्ण समय का उपयोग किया जाता है। एक दुर्लभ अपवाद है जो इंगित करने योग्य है जो सापेक्ष समय के मूल्य को स्पष्ट करना चाहिए। भविष्य की घटनाओं के लिए जो भविष्य में काफी दूर हैं जहां निरपेक्ष समय के बारे में अनिश्चितता हो सकती है जिस पर कुछ हो सकता है, एक सापेक्ष टाइमस्टैम्प का उपयोग करें। यहाँ एक वास्तविक दुनिया का उदाहरण है:

मान लीजिए कि यह वर्ष 2004 है और आपको 31 अक्टूबर 2008 को दोपहर 1 बजे यूएस के वेस्ट कोस्ट (यानी America/Los_Angeles पर डिलीवरी शेड्यूल करने की आवश्यकता है। /PST8PDT ) यदि आपने ’2008-10-31 21:00:00.000000+00’::TIMESTAMP WITH TIME ZONE का उपयोग करके निरपेक्ष समय का उपयोग करके संग्रहीत किया है , डिलीवरी दोपहर 2 बजे दिखाई देती क्योंकि अमेरिकी सरकार ने 2005 का ऊर्जा नीति अधिनियम पारित किया जिसने दिन के उजाले की बचत के समय को नियंत्रित करने वाले नियमों को बदल दिया। 2004 में जब वितरण निर्धारित किया गया था, दिनांक 10-31-2008 प्रशांत मानक समय होता (+8000 ), लेकिन वर्ष 2005+ से शुरू होकर टाइमज़ोन डेटाबेस ने माना कि 10-31-2008 प्रशांत डेलाइट सेविंग टाइम होता (+0700 ) समय क्षेत्र के साथ एक सापेक्ष टाइमस्टैम्प को संग्रहीत करने से सही डिलीवरी शेड्यूल होता क्योंकि एक सापेक्ष टाइमस्टैम्प कांग्रेस की गैर-सूचित छेड़छाड़ से प्रतिरक्षा है। जहां शेड्यूलिंग चीजों के लिए सापेक्ष बनाम पूर्ण समय का उपयोग करने के बीच कटऑफ एक अस्पष्ट रेखा है, लेकिन मेरे अंगूठे का नियम यह है कि भविष्य में किसी भी चीज़ के लिए शेड्यूलिंग 3-6mo से आगे सापेक्ष टाइमस्टैम्प का उपयोग करना चाहिए (अनुसूचित =पूर्ण बनाम नियोजित =रिश्तेदार ???).

अन्य/अंतिम प्रकार का सापेक्ष समय INTERVAL . है . उदाहरण:"उपयोगकर्ता के लॉग इन करने के 20 मिनट बाद सत्र समाप्त हो जाएगा"। एक INTERVAL निरपेक्ष टाइमस्टैम्प के साथ सही ढंग से उपयोग किया जा सकता है (TIMESTAMP WITH TIME ZONE ) या सापेक्ष टाइमस्टैम्प (TIMESTAMP WITHOUT TIME ZONE ) यह कहना भी उतना ही सही है, "एक सफल लॉगिन (login_utc + session_duration) के बाद एक उपयोगकर्ता सत्र 20 मिनट समाप्त हो जाता है" या "हमारी सुबह की नाश्ता बैठक केवल 60 मिनट तक चल सकती है (recurring_start_time + Meeting_length)"।

अंतिम भ्रम की स्थिति:DATE , TIME , TIME WITHOUT TIME ZONE और TIME WITH TIME ZONE सभी सापेक्ष डेटा प्रकार हैं। उदाहरण के लिए:'2011-05-28'::DATE एक सापेक्ष तिथि का प्रतिनिधित्व करता है क्योंकि आपके पास कोई समय क्षेत्र जानकारी नहीं है जिसका उपयोग मध्यरात्रि की पहचान के लिए किया जा सकता है। इसी तरह, '23:23:59'::TIME सापेक्ष है क्योंकि आप या तो समय क्षेत्र या DATE . नहीं जानते हैं समय का प्रतिनिधित्व किया। यहां तक ​​कि '23:59:59-07'::TIME WITH TIME ZONE . के साथ भी , आप नहीं जानते कि DATE . क्या है होगा। और अंत में, DATE एक समय क्षेत्र के साथ वास्तव में एक DATE नहीं है , यह एक TIMESTAMP WITH TIME ZONE . है :

test=> SET timezone = 'America/Los_Angeles';
SET
test=> SELECT '2011-05-11'::DATE AT TIME ZONE 'UTC';
      timezone       
---------------------
 2011-05-11 07:00:00
(1 row)

test=> SET timezone = 'UTC';
SET
test=> SELECT '2011-05-11'::DATE AT TIME ZONE 'UTC';
      timezone       
---------------------
 2011-05-11 00:00:00
(1 row)

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. यह जांचने के 5 तरीके कि क्या PostgreSQL में कोई तालिका मौजूद है

  2. PostgreSQL फ़ंक्शन कॉल

  3. PostgreSQL में एक बाधा का नाम कैसे खोजें

  4. पोस्टग्रेज में pg_trgm . के साथ समानता कार्य

  5. Django के साथ PostgreSQL स्कीमा / नेमस्पेस