IDENTITY_INSERT को एक समय में केवल एक टेबल पर अनुमति क्यों दी जाती है?


20

यह मामला है कि IDENTITY_INSERT को केवल एक समय में एक डेटाबेस तालिका में चालू किया जा सकता है, लेकिन क्यों? चूंकि IDENTITYकॉलम विश्व स्तर पर अद्वितीय नहीं हैं, इसलिए मैं किसी भी खतरनाक स्थिति के बारे में नहीं सोच सकता, जो एक ही समय में एक से अधिक टेबल में पहचान सम्मिलित करने के कारण हो सकती है (कम से कम खतरनाक नहीं है आमतौर पर IDENTITY INSERT के साथ फ्रॉडिंग)।

आइडेंटिटी इंसर्ट का उपयोग शायद ही कभी किया जाना चाहिए लेकिन कठिन सीमा का कारण क्या है?


1
शायद, यह शायद ही कभी इस्तेमाल किया जाता है?
रेमस रूसु 19

@RemusRusanu जो मैं सोच रहा था, उस तरह का है या यह सुनिश्चित करने के लिए कि आप गलती से कई तालिकाओं के लिए II को छोड़ नहीं रहे हैं।
बेन ब्रोका

@ क्यों इसे गलती से एक टेबल के लिए गलती से छोड़ने से कई गुना ज्यादा गलती से छोड़ दिया जाता है? दोनों एक ही तरह के मुद्दे को जन्म दे सकते हैं। मैं वास्तव में आपके प्रश्न के बारे में उत्सुक हूं, और मुझे नहीं लगता कि निवारक उत्तर है, या हमें इंजन में बहुत अधिक प्रतिबंध हैं। लेकिन मैं इस बात से सहमत हूं कि यदि आपको लगता है कि आपको अक्सर ऐसा करने की आवश्यकता है, तो शायद कुछ संदिग्ध है।
हारून बर्ट्रेंड

@AaronBertrand यह नहीं है, जैसा कि मैंने Q में निहित है। निवारक के बारे में निश्चित नहीं है, क्योंकि SQL सर्वर आरक्षित कॉलम के साथ आपके कॉलम का नामकरण करने की कई अन्य बुरी प्रथाओं की अनुमति देता है (कभी-कभी भले ही आप उपयोग न करें!]
बेन ब्रोका

@ सही है कि आप के लिए जरूरी नहीं था, लेकिन किसी भी पाठक के लिए जो सवाल पर आया था।
हारून बर्ट्रेंड

जवाबों:


12

मुझे लगता है कि इसे कठिन बनाना है। यदि आप इसे हर समय छोड़ सकते हैं, तो एक पहचान क्षेत्र भी क्यों हो सकता है?

वास्तव में प्रतिबंधों की एक जोड़ी है, हालांकि:

  • यह केवल उस संबंध पर कायम है
  • यह प्रति कनेक्शन केवल एक टेबल पर ही तय होता है

कनेक्शन-संबंधित प्रतिबंधों के आधार पर, मुझे लगता है कि यह मुख्य रूप से है, इसलिए यह गलती से कभी नहीं छोड़ा गया है।

कल्पना कीजिए कि अगर किसी ने आपके किसी टेबल पर आईडी डालने को चालू कर दिया है, तो आपको एहसास नहीं हुआ और (सामान्य रूप से) अवैध प्रविष्टि का प्रदर्शन किया गया जिसने आपके आईडी फ़ील्ड की अखंडता को तोड़ दिया?

अगर कोई बाधा या अद्वितीय सूचकांक नहीं है, तो आईडी फ़ील्ड में नकली मान हो सकते हैं ...


1
+1 मुझे लगता है कि डुप्लिकेट के बारे में आपका अंतिम बिंदु बहुत कुछ छूट गया है। फॉक्स सोचते हैं कि अगर वे सेट IDENTITYकरते हैं तो यह भी एक अद्वितीय बाधा बन जाता है। बहुत आसान है, बेशक, अगर वे कोशिश करने के लिए हालांकि।
हारून बर्ट्रेंड

@AaronBertrand लेकिन फिर से, डुप्लिकेट आईडी जोखिम बिल्कुल IDSERT INSERT के साथ किसी भी तालिका पर समान है, हार्ड लिमिट क्यों? मुझे लगता है कि यह केवल कनेक्शन के लिए बनी रहती है एहतियात के रूप में बहुत अधिक समझ में आता है।
बेन ब्रोका

मैं सुझाव नहीं दे रहा था कि डुप्लिकेट आईडी समस्या हार्ड लिमिट का एक कारण थी।
हारून बर्ट्रेंड

6

मेरा अनुमान है कि कार्यान्वयन के कारण यह प्रतिबंध था। एकाधिक तालिका पर इस सेटिंग को अनुमति देना एक संभावित पूर्णता हिट था:

चूंकि यह एक सत्र पैरामीटर है, जिससे सेटिंग को एकल तालिका पर सक्रिय करने की अनुमति मिलती है, जिसका अर्थ है कि यह सत्र पर सर्वर-साइड पर संग्रहीत करने के लिए सरल ध्वज और तालिका का ऑब्जेक्ट आईडी है। हो सकता है कि यह सिर्फ एक पूर्णांक है: 0 यदि कोई IDENTITY_INSERT सक्रिय नहीं है, और तालिका के लिए डेटाबेस + ऑब्जेक्टिड के कुछ कोडिंग हैं।

एक सत्र के भीतर कई तालिकाओं पर सेट किए जाने वाले पैरामीटर की अनुमति देने का मतलब होगा कि सर्वर ऐसी वस्तुओं की एक गतिशील सूची को संग्रहीत करेगा और इसे किसी भी सम्मिलित विवरण के लिए जांच करेगा। एक सत्र की कल्पना करें कि एक हज़ार तालिकाओं के लिए पैरामीटर सक्रिय होता है:

  1. इसका मतलब है कि सर्वर ने सत्र चर में 1000 आइटम आवंटित किए हैं
  2. इसका मतलब यह भी है कि सर्वर को इस सत्र में प्रत्येक सम्मिलित विवरण के लिए 1000 वस्तुओं की सूची की जांच करनी है।

इसके अलावा, मुझे संदेह है कि सेट पहचान_ सर्वर पर सर्वर पर व्यापक प्रदर्शन हिट है। Sybase में एक " पहचान बर्निंग सेट फैक्टर " था, जो केवल एक बार में सहेजे जाने वाले टेबल के पहचान काउंटर के मूल्य को बचाने की अनुमति देता था (मान को स्मृति में रखा जाता है और डिस्क पर एक बार और सर्वर पर लिखा जाता है। बंद करना )। SQL सर्वर समान कोड पर आधारित है, इसलिए संभवतया कुछ तुलनात्मक अनुकूलन है, लेकिन एक टेबल पर पहचान_insert को सक्रिय करना संभवतः सर्वर को हर डालने के लिए पहचान मूल्य को बचाने के लिए विवश करता है, क्योंकि यह अधिकतम अंतराल आकार की गारंटी नहीं दे सकता है। इसलिए यदि एक सत्र एक तालिका में आवेषण पर एक प्रदर्शन हिट बनाता है, तो यह संभवतः स्वीकार्य है, लेकिन यह नहीं कि यदि यह सर्वर पर सभी ऑटो_संचालनों की तालियों पर पूर्ण हिट बना सके ..


+1 शायद यहाँ कुछ सच्चाई है। मैं गैप साइज के तर्क को नहीं खरीदता, क्योंकि INSERTएक सत्र के लिए केवल एक ही समय में हो सकता है, और मैं आसानी से 10 मिलियन हार्ड-कोडेड IDENTITYमान डाल सकता हूं ।
हारून बर्ट्रेंड

दुर्घटना के मामले में क्या होता है, यह गैप साइज से संबंधित है: सिबेस पर, अगर सर्वर क्रैश होता है तो आखिरी पहचान खो जाती है (यह मेमोरी में थी), इसलिए यह एक अंतर छोड़ कर फिर से शुरू होता है (पहचान बर्निंग सेट फैक्टर देखें)
ओलिवियर

तो SQL सर्वर में आप यह सुझाव दे रहे हैं कि यदि पहचान स्तंभ के साथ 1,000,000 पंक्तियों को सम्मिलित करते समय इंजन दुर्घटनाग्रस्त हो जाता है या SET IDENTITY_INSERTसक्षम होने पर 1,000,000 हार्ड-कोडित मानों के साथ पहचान स्तंभ को ओवरराइड करता है? मैं सिर्फ यह सुझाव दे रहा हूं कि गैप साइज किसी भी टेबल को प्रभावित करने की तुलना में किसी भी टेबल को अलग-अलग तरीके से प्रभावित नहीं करता है।
हारून बर्ट्रेंड

मेरा अनुमान - मेरे पास इस बात का कोई प्रमाण नहीं है - यह है कि एक मेज पर सेट IDENTITY_INSERT प्रत्येक डालने पर ऑटोइन्क्रिमेंट के राइट-टू-डिस्क को मजबूर करता है। तर्क यह होगा कि आपके द्वारा डाला जाने वाला मूल्य कुछ भी हो सकता है, सर्वर "ओके" पर विचार नहीं कर सकता है, अगर मैं हर 1000 पंक्तियों में केवल एक बार डिस्क पर लिखता हूं, तो दुर्घटना के मामले में मैं सुरक्षित रूप से 1000 को अंतिम मूल्य में जोड़ सकता हूं जिसे मैंने बचाया "
ओलिवियर एस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.