प्रथम
: आप शायद सभी तीन स्तंभों की जरूरत नहीं है old_id
, external_id
, new_id
। new_id
स्तंभ, एक जा रहा है IDENTITY
, प्रत्येक पंक्ति के लिए एक नया मूल्य भी जब आप में सम्मिलित होगा, external_id
। लेकिन, बीच old_id
और external_id
, वे बहुत अधिक पारस्परिक रूप से अनन्य हैं: या तो पहले से ही एक old_id
मूल्य है या वह कॉलम, वर्तमान गर्भाधान में, बस NULL
उपयोग करने पर external_id
या होगा new_id
। चूँकि आप एक नई "बाहरी" आईडी को एक पंक्ति में नहीं जोड़ेंगे जो पहले से मौजूद है (जिसका old_id
मान है), और इसके लिए आने वाले कोई भी नए मान नहीं होंगे old_id
, तो इसका उपयोग किया जा सकने वाला एक कॉलम हो सकता है दोनों उद्देश्यों के लिए।
तो, external_id
कॉलम से छुटकारा पाएं और old_id
कुछ old_or_external_id
या कुछ भी होने का नाम बदलें । इसके लिए किसी भी वास्तविक परिवर्तन की आवश्यकता नहीं होनी चाहिए, फिर भी कुछ जटिलताएं कम हो जाती हैं। external_id
यदि आपको पहले से ही सम्मिलित करने के लिए एप्लिकेशन कोड लिखा है, तो भी आपको कॉलम को कॉल करने की आवश्यकता हो सकती है , भले ही उसमें "पुराने" मान हों external_id
।
यह नई संरचना को घटाता है:
PkId AS AS COALESCE(old_or_external_id, new_id, -1) PERSISTED NOT NULL,
old_or_external_id INT NULL, -- values from existing record OR passed in from app
new_id INT IDENTITY(2000000, 1) NOT NULL
अब आपने 12 बाइट्स के बजाय प्रति पंक्ति केवल 8 बाइट्स जोड़े हैं (यह मानते हुए कि आप SPARSE
विकल्प या डेटा संपीड़न का उपयोग नहीं कर रहे हैं )। और आपको किसी भी कोड, T-SQL या App कोड को बदलने की आवश्यकता नहीं थी।
दूसरा
सरलीकरण के इस रास्ते को जारी रखते हुए, आइए देखें कि हमने क्या छोड़ा है:
old_or_external_id
कॉलम को या तो पहले से ही मान होते हैं, या ऐप्लिकेशन से एक नया मूल्य दिया जाएगा, या के रूप में छोड़ दिया जाएगा NULL
।
new_id
हमेशा एक नया मूल्य होगा, लेकिन अगर है कि मूल्य केवल उपयोग किया जाएगा old_or_external_id
स्तंभ है NULL
।
वहाँ एक समय था जब तुम दोनों में मूल्यों की आवश्यकता होगी कभी नहीं है old_or_external_id
और new_id
। दोनों स्तंभ के कारण मान हैं जब हाँ, कई बार ऐसा हो जाएगा new_id
एक किया जा रहा है IDENTITY
, लेकिन उन new_id
मूल्यों को नजरअंदाज कर दिया जाता है। फिर, ये दो क्षेत्र परस्पर अनन्य हैं। तो अब क्या?
अब हम इस बात पर गौर कर सकते हैं कि हमें external_id
पहली जगह की आवश्यकता क्यों थी । यह ध्यान में रखते हुए कि एक IDENTITY
कॉलम का उपयोग करना संभव है SET IDENTITY_INSERT {table_name} ON;
, आप किसी भी स्कीमा परिवर्तन को पूरा करने के साथ दूर हो सकते हैं, और केवल INSERT
स्टेटमेंट / ऑपरेशंस SET IDENTITY_INSERT {table_name} ON;
और SET IDENTITY_INSERT {table_name} OFF;
स्टेटमेंट्स को लपेटने के लिए अपने ऐप कोड को संशोधित कर सकते हैं । फिर आपको यह निर्धारित करने की आवश्यकता है कि IDENTITY
कॉलम को (नए उत्पन्न मूल्यों के लिए) रीसेट करने के लिए कौन सी शुरुआती सीमा है क्योंकि इसे उन मूल्यों से ऊपर होना चाहिए जो उच्च मूल्य सम्मिलित करने के बाद से ऐप कोड डाले जाएंगे, जिससे अगला ऑटो-जेनरेट किया गया मान होगा वर्तमान अधिकतम मूल्य से अधिक हो। लेकिन आप हमेशा एक मान डाल सकते हैं जो IDENT_CURRENT मान के नीचे है ।
संयोजन old_or_external_id
और new_id
कॉलम भी 2, या यहाँ तक 3 होने के इरादे के बाद से स्वत: जनरेट मूल्यों और एप्लिकेशन-उत्पन्न मूल्यों के बीच एक ओवरलैपिंग मूल्य स्थिति में चल रहा है की संभावना को बढ़ा नहीं है, कॉलम, उन्हें एक प्राथमिक कुंजी मूल्य में गठबंधन करने के लिए है और वे हमेशा अद्वितीय मूल्य हैं।
इस दृष्टिकोण में, आपको बस निम्नलिखित की आवश्यकता है:
जा रहा है के रूप में टेबल छोड़ दें:
PkId INT IDENTITY(1,1) PRIMARY KEY
यह प्रत्येक पंक्ति में 8 या 12 के बजाय 0 बाइट्स जोड़ता है।
- एप्लिकेशन-जनरेट किए गए मानों के लिए प्रारंभिक सीमा निर्धारित करें। ये प्रत्येक तालिका में वर्तमान MAX मान से अधिक होंगे, लेकिन स्वतः-जनरेट किए गए मानों के लिए न्यूनतम मान क्या होगा।
- निर्धारित करें कि ऑटो-जेनरेट की गई रेंज किस मूल्य पर शुरू होनी चाहिए। वर्तमान अधिकतम मूल्य और बढ़ने के लिए बहुत सारे कमरे के बीच में बहुत जगह होनी चाहिए , ऊपरी सीमा पर जानना सिर्फ 2.14 बिलियन से अधिक है। फिर आप इस नए न्यूनतम बीज मान को DBCC CHECKIDENT के माध्यम से सेट कर सकते हैं ।
- एप्लिकेशन कोड INSERTs
SET IDENTITY_INSERT {table_name} ON;
और SET IDENTITY_INSERT {table_name} OFF;
विवरणों में लपेटें ।
सेकंड, पार्ट बी
सीधे ऊपर दिए गए दृष्टिकोण पर भिन्नता -1 के साथ शुरू होने और वहां से नीचे जाने वाले ऐप कोड डालने के मूल्यों के लिए होगी । यह उन IDENTITY
मूल्यों को छोड़ देता है जो केवल ऊपर जा रहे हैं । यहां लाभ यह है कि आप केवल स्कीमा को जटिल नहीं करते हैं, आपको ओवरलैपिंग आईडी (यदि एप्लिकेशन-जनरेट किए गए मान नए ऑटो-जनरेटेड रेंज में चलते हैं) में चलने के बारे में चिंता करने की आवश्यकता नहीं है। यह केवल एक विकल्प है यदि आप पहले से ही नकारात्मक आईडी मानों का उपयोग नहीं कर रहे हैं (और लोगों को ऑटो-जनरेट किए गए स्तंभों पर नकारात्मक मानों का उपयोग करना बहुत दुर्लभ लगता है, इसलिए यह अधिकांश स्थितियों में संभावना होना चाहिए)।
इस दृष्टिकोण में, आपको बस निम्नलिखित की आवश्यकता है:
जा रहा है के रूप में टेबल छोड़ दें:
PkId INT IDENTITY(1,1) PRIMARY KEY
यह प्रत्येक पंक्ति में 8 या 12 के बजाय 0 बाइट्स जोड़ता है।
- ऐप-जनरेट वैल्यू के लिए शुरुआती रेंज होगी
-1
।
- एप्लिकेशन कोड INSERTs
SET IDENTITY_INSERT {table_name} ON;
और SET IDENTITY_INSERT {table_name} OFF;
विवरणों में लपेटें ।
यहां आपको अभी भी करने की आवश्यकता है IDENTITY_INSERT
, लेकिन: आप किसी भी नए कॉलम को नहीं जोड़ते हैं, किसी भी IDENTITY
कॉलम को "रीसेट" करने की आवश्यकता नहीं है , और ओवरलैप्स का कोई भविष्य का जोखिम नहीं है।
सेकंड, भाग 3
इस दृष्टिकोण का एक अंतिम बदलाव संभवतः IDENTITY
स्तंभों को स्वैप करना होगा और इसके बजाय अनुक्रमों का उपयोग करना होगा । इस दृष्टिकोण को लेने का कारण ऐप कोड डालने के मूल्यों को सक्षम करने में सक्षम होना चाहिए: ऑटो-जेनरेट किए गए रेंज के ऊपर सकारात्मक (नीचे नहीं), और इसकी कोई आवश्यकता नहीं है SET IDENTITY_INSERT ON / OFF
।
इस दृष्टिकोण में, आपको बस निम्नलिखित की आवश्यकता है:
- क्रीक दृश्य का उपयोग कर अनुक्रम बनाएँ
IDENTITY
स्तंभ को उस नए कॉलम में कॉपी करें जिसमें IDENTITY
संपत्ति नहीं है , लेकिन फ़ंक्शन के लिए NEXT VALUEDEFAULT
का उपयोग करके एक बाधा है :
PkId INT PRIMARY KEY CONSTRAINT [DF_TableName_NextID] DEFAULT (NEXT VALUE FOR...)
यह प्रत्येक पंक्ति में 8 या 12 के बजाय 0 बाइट्स जोड़ता है।
- एप्लिकेशन-जनरेट किए गए मानों के लिए आरंभिक सीमा उस से ऊपर होगी जो आपको लगता है कि स्वतः-जनरेट किए गए मान एप्रोच करेंगे।
- एप्लिकेशन कोड INSERTs
SET IDENTITY_INSERT {table_name} ON;
और SET IDENTITY_INSERT {table_name} OFF;
विवरणों में लपेटें ।
फिर भी , आवश्यकता के कारण उस कोड के साथ या SCOPE_IDENTITY()
फिर @@IDENTITY
भी ठीक से काम करता है, अनुक्रम पर स्विच करना वर्तमान में एक विकल्प नहीं है क्योंकि ऐसा प्रतीत होता है कि अनुक्रम के लिए उन कार्यों के बराबर नहीं है :-( दुखद!