2012-06-12 15 views
38

में पूर्ण मान मुझे प्राथमिक कुंजी बनाने वाले कई स्तंभों के साथ एक तालिका मिली है। संग्रहीत डेटा की प्रकृति इन क्षेत्रों में से कुछ को NULL मानों की अनुमति देती है। मैं इस तरह के रूप में मेरी मेज तैयार की है:मल्टी-कॉलम प्राथमिक कुंजी

CREATE TABLE `test` (
    `Field1` SMALLINT(5) UNSIGNED NOT NULL, 
    `Field2` DECIMAL(5,2) UNSIGNED NULL DEFAULT NULL, 
    PRIMARY KEY (`Field1`, `Field2`) 
) 
COLLATE='latin1_swedish_ci' 
ENGINE=InnoDB; 

हालांकि, यह इस तरह से पता चलता है जब मैं describe test चलाएँ:

|| *Field* || *Type*    || *Null* || *Key* || *Default* || *Extra* 
|| Field1 || smallint(5) unsigned || NO  || PRI ||   ||   
|| Field2 || decimal(5,2) unsigned || NO  || PRI || 0.00  ||   

और जब कोई NULL मूल्य डालने मैं एक त्रुटि जा रहे हैं।

स्तंभ 'फ़ील्ड 2' अशक्त

इस है क्योंकि एक क्षेत्र है कि एक प्राथमिक कुंजी का हिस्सा है नल नहीं हो सकता नहीं हो सकता है? NULL के लिए '0' का उपयोग करने के अलावा मेरे विकल्प क्या हैं?

+2

वीजे शाह के लिंक के लिए धन्यवाद, @Tomalak [उत्कृष्ट बिंदु] बनाता है (http://stackoverflow.com/a/386061/673991) है कि इस प्रतिबंध को बुनियादी एसक्यूएल से इस प्रकार है सिद्धांत यह है कि, चूंकि प्राथमिक कुंजी के हिस्सों की तुलना प्रत्येक पंक्ति से प्रत्येक पंक्ति से की जानी चाहिए, और "** न्यूल तुलना की तुलना नहीं हो सकता है - इस तरह की तुलना का परिणाम हमेशा नल ** होगा" जो प्राथमिक कुंजी विशिष्टता को लागू करता है गैर-शून्य कॉलम। –

उत्तर

34

MySQL प्रलेखन से:

प्राथमिक कुंजी एक अद्वितीय सूचकांक जहां सभी प्रमुख स्तंभों नहीं NULL के रूप में परिभाषित किया जाना चाहिए। यदि वे
स्पष्ट रूप से न्यूल के रूप में घोषित नहीं किए जाते हैं, तो MySQL उन्हें स्पष्ट रूप से (और चुपचाप) घोषित करता है। एक तालिका में केवल एक प्राथमिक कुंजी हो सकती है। प्राथमिक कुंजी का नाम हमेशा प्राथमिक होता है, जो इस प्रकार किसी अन्य प्रकार की अनुक्रमणिका के नाम के रूप में उपयोग नहीं किया जा सकता है।

http://dev.mysql.com/doc/refman/5.1/en/create-table.html

फ़ील्ड 2 शून्य हो सकता है, तो मैं सवाल क्यों आप इसे प्राथमिक कुंजी के हिस्से के रूप की जरूरत है, क्योंकि आप तो फ़ील्ड 1 की जरूरत है सभी पंक्तियों में अलग होने के लिए। इसलिए फील्ड 1 प्राथमिक कुंजी के रूप में पर्याप्त होना चाहिए। आप फील्ड 2 पर एक अलग प्रकार की अनुक्रमणिका बना सकते हैं।

+12

आश्चर्य की बात है कि यह किसी को कॉलम का उपयोग करके प्राथमिक कुंजी बनाने की अनुमति देता है जिसे नल स्वीकार करने के रूप में परिभाषित किया गया है। – Marvo

+1

यही वह परिभाषा है जिसे मैं ढूंढ रहा था लेकिन मुझे नहीं मिला। धन्यवाद। असल में मेरे पास 12 कॉलम हैं जो अभी प्राथमिक कुंजी बनाते हैं। इन मूल्यों में से 5 शून्य हैं। यह एक कैशिंग रणनीति है जहां कैश किए गए अनुरोध में सभी मूल्यों की आवश्यकता नहीं है। मेरा विचार था कि पीके के रूप में एक ऑटोइनक्रिकमेंट वैल्यू का उपयोग करने और अन्य सभी पर एक अद्वितीय इंडेक्स जोड़ने से एक समग्र प्राथमिक कुंजी सस्ता होगी। ऐसा लगता है कि मुझे उस तरह जाना है। – simbabque

+7

@ गिरिश मैंने अभी इस समस्या में भाग लिया है और मैं भी एक शून्य क्षेत्र चाहता हूं। मेरे मामले में, पीके दो फ़ील्ड है, उनमें से एक शून्य है, लेकिन मुझे दूसरी फ़ील्ड नल के साथ सबसे अधिक पंक्ति चाहिए, तो यह वैध पीके होना चाहिए। आईएमएचओ, यह MySQL से एक असफल कल्पना है। – Seb

7

प्राथमिक कुंजी कहा गया है कि स्तंभ NULL मान नहीं होने चाहिए साथ काम करते हैं। तो समग्र प्राथमिक कुंजी को परिभाषित करने के लिए उपयोग किए गए कॉलम NULL नहीं होने जा रहे हैं।

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

इसके अलावा, इस धागे को देखें: What's wrong with nullable columns in composite primary keys?

यह लिंक समग्र कुंजी में निरंतर कॉलम की संभावना के बारे में मूल्यवान जानकारी प्रदान करता है!

+3

नीचे दिए गए viyay उत्तर में जुड़े प्रश्न का दूसरा उत्तर देखें, आपके इनपुट के लिए धन्यवाद। मैं ओरेकल पर नहीं हूं लेकिन हालांकि MySQL पर हूं। – simbabque

3

आप इस तरह अद्वितीय कुंजी का उपयोग कर सकते हैं:

mysql> CREATE TABLE `test` (
    ->  `Field1` SMALLINT(5) UNSIGNED NOT NULL, 
    ->  `Field2` DECIMAL(5,2) UNSIGNED NULL DEFAULT NULL, 
    ->  UNIQUE KEY (`Field1`, `Field2`) 
    ->) 
    -> COLLATE='latin1_swedish_ci' 
    -> ENGINE=InnoDB; 
Query OK, 0 rows affected (0.03 sec) 

mysql> 
mysql> desc test 
    -> ; 
+--------+-----------------------+------+-----+---------+-------+ 
| Field | Type     | Null | Key | Default | Extra | 
+--------+-----------------------+------+-----+---------+-------+ 
| Field1 | smallint(5) unsigned | NO | MUL | NULL |  | 
| Field2 | decimal(5,2) unsigned | YES |  | NULL |  | 
+--------+-----------------------+------+-----+---------+-------+ 
2 rows in set (0.01 sec) 
18

प्राथमिक कुंजी दोनों अद्वितीय और रिक्त नहीं स्तंभ बनाने के लिए उपयोग किया जाता है

Inorder डालने के लिए डालने शून्य मान रूप field2 बनाने अद्वितीय

अद्वितीय बाधा क्षेत्र बनाते हैं निकालता है डुप्लिकेट लेकिन अनुमति देने के अशक्त मूल्यों

+1

इस प्रश्न का उत्तर, धन्यवाद। स्वीकृत उत्तर गलत था। – singe3

+1

@ singe3 अच्छी तरह से, सवाल नहीं था कि मैं एक समान मूल्य_ के साथ एक सूचकांक कैसे बना सकता हूं, लेकिन _ प्राथमिक प्राथमिक_ में मेरा कोई मूल्य क्यों नहीं हो सकता है। मुझे खुशी है कि एक अनूठी कुंजी आपको एक नल फ़ील्ड की मदद करने में मदद करती है, लेकिन यह सवाल का जवाब नहीं देती है। स्वीकृत उत्तर करता है। – simbabque

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