2009-06-13 18 views
11

में पहचान कॉलम अधिकतम मूल्य SQLite डेटाबेस के बारे में मेरे पास एक पूरी तरह अकादमिक प्रश्न है।एसक्यूएलएट डीबी

मैं अपने WinForm प्रोजेक्ट में डेटाबेस का उपयोग करने के लिए SQLite.net का उपयोग कर रहा हूं, और जब मैं एक नई तालिका स्थापित कर रहा था, तो मुझे आईडी कॉलम के अधिकतम मानों के बारे में सोचना पड़ा।

मैं अपने [ID] स्तंभ, जो SQLite.net DataType Mappings के अनुसार, DbType.Int64 के बराबर है के लिए IDENTITY का उपयोग करें। मैं सामान्य रूप से शून्य पर अपना आईडी कॉलम शुरू करता हूं (उस पंक्ति के साथ एक परीक्षण रिकॉर्ड के रूप में) और डेटाबेस ऑटो-वृद्धि है।

अधिकतम मूल्य (Int64.MaxValue) 9,223,372,036,854,775,807 है। मेरे उद्देश्यों के लिए, मैं उस अधिकतम तक पहुंचने पर सतह को कभी भी खरोंच नहीं करूंगा, लेकिन डेटाबेस में क्या होता है? इस पर पढ़ने की कोशिश करते समय, मैंने पाया कि डीबी 2 स्पष्ट रूप से ऋणात्मक मूल्य (-9,223,372,036,854,775,807) के आसपास मूल्य को "लपेटता है" और वहां से वृद्धि करता है, जब तक कि डेटाबेस पंक्तियों को सम्मिलित नहीं कर सकता क्योंकि आईडी कॉलम अद्वितीय होना चाहिए।

क्या यह SQLite और/या अन्य डेटाबेस इंजन में होता है?

+0

SQLite का आधिकारिक दस्तावेज http://www.sqlite.org/autoinc.html पर इसे कवर करता है, मैंने नीचे एक और विस्तृत उत्तर जोड़ा है। –

उत्तर

24

मुझे संदेह है कि कोई भी निश्चित रूप से जानता है, क्योंकि यदि प्रति सेकंड एक लाख पंक्तियां डाली जा रही हैं, तो लपेटने के आसपास के जोखिम बिंदु तक पहुंचने में लगभग 2 9 2,471 वर्ष लगेंगे - और डाटाबेस उस के एक छोटे से हिस्से के लिए आसपास रहे हैं समय (वास्तव में, तो होमो सेपियंस है ;-)।

+1

मुझे हमेशा इस तरह की सैनिटी जांच पसंद है जब मैं समस्याओं पर लटका देता हूं, हालांकि मैं आमतौर पर उनको सोचने वाला नहीं हूं। : -/ – tgray

+3

शायद ही कभी "छोटा अंश"। विकिपीडिया के मुताबिक http://en.wikipedia.org/wiki/Homo_sapiens Homo Sapiens उस समय अवधि के शायद दो तिहाई के आसपास रहा है। –

1

मैं किसी भी विशिष्ट डीबी 2 कार्यान्वयन तर्क से बात नहीं कर सकता, लेकिन आपके द्वारा वर्णित "चारों ओर लपेटें" व्यवहार उन संख्याओं के लिए मानक है जो two's complement के माध्यम से हस्ताक्षर लागू करते हैं।

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

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

7

पहचान SQLite में स्वतः वृद्धि के लिए वास्तव में उचित तरीका नहीं है। आपको ऐप परत में वृद्धि करने की आवश्यकता होगी। SQLite खोल में, कोशिश करें:

create table bar (id IDENTITY, name VARCHAR); 
insert into bar (name) values ("John"); 
select * from bar; 

आप देखेंगे कि आईडी बस शून्य है। SQLite पहचान के लिए कोई विशेष महत्व नहीं देता है, इसलिए यह मूल रूप से एक सामान्य (untyped) कॉलम है।

दूसरी ओर, यदि आप कार्य करें:

create table baz (id INTEGER PRIMARY KEY, name VARCHAR); 
insert into baz (name) values ("John"); 
select * from baz; 

यह के रूप में मुझे लगता है कि आप उम्मीद कर 1 हो जाएगा।

ध्यान दें कि there is also एक इंटेग्रियर प्राथमिक कुंजी ऑटोमेशन। बुनियादी अंतर यह है कि ऑटोमेशन सुनिश्चित करता है कि कुंजियों का पुन: उपयोग नहीं किया जाता है। तो यदि आप जॉन को हटाते हैं, तो 1 को आईडी के रूप में कभी भी पुन: उपयोग नहीं किया जाएगा।किसी भी तरह से, यदि आप प्राथमिक कुंजी (वैकल्पिक ऑटोमेशन के साथ) का उपयोग करते हैं और आईडी से बाहर निकलते हैं, तो SQLite को SQLITE_FULL के साथ विफल होना चाहिए, चारों ओर लपेटें नहीं।

पहचान का उपयोग करके, आप (0 अप्रासंगिक) संभावना को खोलते हैं कि आपके ऐप डीबी कभी पूर्ण होने पर गलत तरीके से लपेट जाएंगे। यह काफी संभव है, क्योंकि SQLite में पहचान कॉलम में कोई मान हो सकता है (नकारात्मक इनट्स सहित)। दोबारा प्रयास करें:

insert into bar VALUES ("What the hell", "Bill"); 
insert into bar VALUES (-9, "Mary"); 

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

+1

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

3

http://www.sqlite.org/autoinc.html पर प्रलेखन इंगित करता है कि ROWID इसकी अधिकतम संख्या तक पहुंचने के बाद यादृच्छिकरण के माध्यम से एक अप्रयुक्त मूल्य खोजने का प्रयास करेगा।

AUTOINCREMENT के लिए यह इस तालिका में सम्मिलित करने के लिए सभी प्रयास पर SQLITE_FULL साथ विफल हो जाएगा, एक बार तालिका में एक अधिकतम मूल्य था:

तालिका में पहले सबसे बड़ा संभव ROWID के साथ एक पंक्ति पर कार्य किया है, तो तो नए आईएनएसईआरटी की अनुमति नहीं है और एक नई पंक्ति डालने का कोई प्रयास SQLITE_FULL त्रुटि के साथ विफल हो जाएगा।

यह आवश्यक है, क्योंकि AUTOINCREMENT गारंटी देता है कि आईडी एकान्त रूप से बढ़ रही है।

संबंधित मुद्दे