CURRENT_TIMESTAMP को एक प्राथमिक कुंजी के रूप में उपयोग किया जा सकता है?


10

CURRENT_TIMESTAMPएक के रूप में इस्तेमाल किया जा सकता है PRIMARY KEY?

क्या एक संभावना है कि दो या अधिक अलग-अलग INSERT, समान हों CURRENT_TIMESTAMP?


3
मैंने एक ऐप के बारे में सुना जो टाइमस्टैम्प का पीके के रूप में उपयोग करके कोड किया गया था, 1990 के दशक में। दस साल बाद पीसी तेजी से बन गए और टाइमस्टैम्प का दोहराव हो गया। इसने बहुत गंभीर समस्याएं पैदा कीं, क्योंकि ऐप की कार्यक्षमता अत्यधिक महत्वपूर्ण थी। इसके अलावा, पीके विशिष्टता को पूरे ऐप में ठीक से लागू नहीं किया गया था।
विक्टर डि लियो

क्या ऐसी संभावना है कि दो या अधिक विभिन्न INSERT, समान CURRENT_TIMESTAMP प्राप्त करें? यह टक्कर के लिए पर्याप्त एक क्वेरी 2 रिकॉर्ड सम्मिलित है। अतः किसी विषय के प्रश्न का उत्तर "NO" है।
अकिना


3
मैं उत्सुक हूं कि आप ऐसा क्यों चाहते हैं?
नेने

@Nanne मुझे इस पर संदेह है: MySQL के पास स्वचालित रूप से बढ़े हुए पूर्णांक आईडी (क्षेत्र के लिए एक स्वतः-सुधार विशेषता) की बहुत अच्छी हैंडलिंग है। PostgreSQL नहीं है, इसमें एक सीरियल प्रकार है जो बहुत कम सुंदर है।
पीटर - मोनिका

जवाबों:


18

प्रलेखन के अनुसार , CURRENT_TIMESTAMPसूक्ष्मदर्शी सूक्ष्मदर्शी है। इस प्रकार, टकराव की संभावना कम है, लेकिन संभव है।

अब एक बग की कल्पना करें जो बहुत कम ही होता है , और डेटाबेस त्रुटियों का कारण बनता है। इसे डीबग करना कितना कठिन है? यह कम से कम नियतात्मक है जो एक से अधिक बग बग है।

अधिक व्यापक संदर्भ: आप शायद सीक्वेंस के साथ इन छोटी बारीकियों से बचना चाहते हैं, जो विशेष रूप से कष्टप्रद है यदि आप MySQL के आदी हैं।

इसके अलावा, यदि आप लेनदेन का उपयोग कर रहे हैं (ज्यादातर वेब फ्रेमवर्क, विशेष रूप से जावा वाले, करते हैं!), तो टाइमस्टैम्प एक लेनदेन के अंदर ही होगा! प्रदर्शन:

postgres=# begin;
BEGIN
postgres=# select current_timestamp;
       current_timestamp       
-------------------------------
 2018-08-06 02:41:42.472163+02
(1 Zeile)

postgres=# select current_timestamp;
       current_timestamp       
-------------------------------
 2018-08-06 02:41:42.472163+02
(1 Zeile)

फिर मिलते हैं? दो का चयन, बिल्कुल उसी परिणाम। मैं इतनी जल्दी टाइप नहीं करता। ;-)

-

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

md5(mother_name || '-' || given_name || '-' birthday);

आईडी के रूप में। इसके अलावा, आप एक CreationDateतालिका का उपयोग करने के बाद एक कॉलम का उपयोग कर सकते हैं , लेकिन यह एक कुंजी नहीं है (जो कि आईडी है)।

Ps सामान्य तौर पर, अपने DB को इतना निर्धारक बनाना एक बहुत अच्छा अभ्यास है, क्योंकि यह संभव है। यानी एक ही ऑपरेशन को DB में ठीक उसी परिवर्तन को बनाना चाहिए । कोई भी टाइमस्टैम्प-आधारित आईडी इस महत्वपूर्ण विशेषता को विफल करती है। यदि आप डिबग या किसी चीज़ का अनुकरण करना चाहते हैं तो क्या होगा? आप एक ऑपरेशन फिर से करते हैं और एक ही ऑब्जेक्ट को एक अलग आईडी के साथ बनाया जाएगा ... यह वास्तव में पालन करना मुश्किल नहीं है, और यह बहुत काम के घंटे बख्शता है।

Ps2 भविष्य में आपके कोड की जांच करने वाला कोई भी व्यक्ति, उपरोक्त कारणों से टाइमस्टैम्प-जनरेट किए गए आईडी को देखने की सबसे अच्छी राय नहीं होगी।


यहां तक ​​कि अगर आप लेनदेन का उपयोग नहीं कर रहे हैं, तो आप वास्तव में लेन-देन का उपयोग कर रहे हैं (क्योंकि पोस्टग्रैज में नो-ट्रांजेक्शन मोड नहीं है, यह सिर्फ ऑटोोकॉम है)। इसलिए यदि आप INSERTकई पंक्तियों को करते हैं, तो वे सभी समान हो जाते हैं current_timestamp। और फिर आपके पास ट्रिगर होता है ...
केविन

2
मैंने एक ऐप के बारे में सुना है जो 2 लोगों की वजह से टूट गया था और उसी दिन उनका नाम और जन्म हुआ था और उनकी माँ के नाम समान थे। आउच। यदि ऐसा हो सकता है तो यह जल्दी या बाद में होगा।
बालाज्स गन्सिक्स

@BalazsGunics हेलो :-) यह सिर्फ एक उदाहरण था। उदाहरण के लिए, वास्तविक परिदृश्य में, मुझे लगता है कि आईडी को ईमेल पते या चुने हुए उपयोगकर्ता नाम के रूप में देखा जा सकता है (जिसे केवल तभी पंजीकृत किया जा सकता है जब तक वह मौजूद नहीं है) पर्याप्त है। सरकार कुछ व्यक्तिगत पहचान संख्या का उपयोग करने के लिए जाती है, जैसे कि 1 870728 0651। महत्वपूर्ण बात यह है कि एक टाइमस्टैम्प या एक यादृच्छिक मूल्य के लिए एक आईडी को बांधना एक बुरा अभ्यास है, क्योंकि यह डीबी को कम निर्धारक बनाता है।
पीटर - मोनिका

@ बालाज़गनिक्स के अनुसार, एक ही माँ के साथ दो लोग_नाम + दिए_नाम + जन्मदिन, यह अभी भी एक निर्णायक त्रुटि का कारण होगा। प्राथमिक कुंजी टकराव के कारण आवेषण में होने वाले दो लेनदेन एक ही माइक्रोसेकंड में हुए, यह अभी भी एक गैर-नियतात्मक है, और बहुत मुश्किल से पुन: प्रयोज्य समस्या है।
पीटर -

10

वास्तव में नहीं है क्योंकि CURRENT_TIMESTAMP के लिए दो बाद के INSERT (या एक से अधिक INSERT कई पंक्तियों के साथ) के लिए दो समान मान प्रदान करना संभव है।

इसके बजाय समय-आधारित UUID का उपयोग करें: uuid_generate_v1mc ()


7

सख्ती से बोलना: नहीं। क्योंकि CURRENT_TIMESTAMPएक फ़ंक्शन है और केवल एक या अधिक टेबल कॉलम एक PRIMARY KEYबाधा बना सकते हैं।

यदि आप PRIMARY KEYडिफ़ॉल्ट मान के साथ एक स्तंभ पर एक बाधा बनाने का मतलब है CURRENT_TIMESTAMP, तो जवाब है: हाँ, आप कर सकते हैं । कुछ भी आपको ऐसा करने से रोकता है, जैसे कुछ भी नहीं आपको अपने बेटे के सिर से सेब की शूटिंग करने से रोकता है। जब आप इसके उद्देश्य को परिभाषित नहीं करते हैं तब भी यह सवाल समझ में नहीं आएगा। कॉलम और टेबल किस प्रकार के डेटा को धारण करने वाले हैं? आप किन नियमों को लागू करने की कोशिश कर रहे हैं?

आमतौर पर, यह विचार डुप्लिकेट कुंजी त्रुटियों में चलाने के लिए बाध्य है क्योंकि CURRENT_TIMESTAMPएक STABLEही लेन-देन के लिए समान मूल्य (लेनदेन का प्रारंभ समय) लौटाने वाला एक फ़ंक्शन है। एक ही लेन-देन में कई INSERTs टकराने के लिए बाध्य हैं - जैसे पहले से सचित्र अन्य उत्तर। नियम पुस्तिका:

चूंकि ये फ़ंक्शन वर्तमान लेन-देन का प्रारंभ समय लौटाते हैं, इसलिए लेनदेन के दौरान उनके मूल्य नहीं बदलते हैं। इसे एक विशेषता माना जाता है: इरादा एक एकल लेनदेन को "वर्तमान" समय की सुसंगत धारणा रखने की अनुमति देना है, ताकि एक ही लेनदेन के भीतर कई संशोधनों में एक ही समय की मुहर लगे।

पोस्टग्रैट्स टाइमस्टैम्प्स को 8-बाइट पूर्णांकों के रूप में लागू किया जाता है जो 6 भिन्नात्मक अंकों (माइक्रोसेकंड रिज़ॉल्यूशन) का प्रतिनिधित्व करता है।

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

मैं अब भी इसके बजाय एक सरोगेट सीरियल प्राथमिक कुंजी का उपयोग करेगा। और UNIQUEटाइमस्टैम्प कॉलम पर एक बाधा जोड़ें । आरडीबीएमएस के कार्यान्वयन के विवरण पर भरोसा न करते हुए, कम संभव जटिलताओं।


यहां तक ​​कि sensor_reading_per_microsecondटकरा सकता है यदि आप पूरी तरह से गारंटी नहीं दे सकते हैं कि प्रत्येक पढ़ने का समय पिछले एक के संबंध में पूरी तरह से सिंक्रनाइज़ है; एक उप-माइक्रोसेकंड विचलन (जो अक्सर असंभव नहीं है) योजना को तोड़ता है। सामान्य तौर पर मैं अभी भी पूरी तरह से इससे बचूंगा। (ध्यान दें, जैसा कि आपने संकेत दिया है, ऐसे मामले में, परिणामी टक्कर वांछनीय हो सकती है!)
10

@ प्रकाश: मैं पूरी तरह से समझौते में हूं। एक गोल छोटे विचलन के बाद अनपेक्षित समय-बदलाव के साथ आपका उदाहरण एक और चेतावनी को दर्शाता है।
एरविन ब्रैंडस्टैटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.