समग्र विदेशी कुंजियों को एक अलग अद्वितीय बाधा की आवश्यकता क्यों है?


10

यहां एक साधारण तालिका है जहां रिकॉर्ड एक ही तालिका में मूल रिकॉर्ड को संदर्भित कर सकते हैं:

CREATE TABLE foo (
    id         SERIAL  PRIMARY KEY,
    parent_id  INT     NULL,
    num        INT     NOT NULL,
    txt        TEXT    NULL,
    FOREIGN KEY (parent_id) REFERENCES foo(id)
);

अतिरिक्त आवश्यकता के साथ कि अन्य क्षेत्र मूल्यों में से एक ( numमाता-पिता और बच्चे के रिकॉर्ड के बीच समान होना चाहिए), मैंने सोचा कि एक समग्र विदेशी कुंजी को चाल करना चाहिए। मैंने आखिरी लाइन बदल दी

    FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)

और मिला ERROR: संदर्भित तालिका "फू" के लिए कोई अद्वितीय बाधा मिलान कुंजी नहीं दी गई है

मैं आसानी से इस बाधा को जोड़ सकता हूं, लेकिन मुझे समझ नहीं आता कि यह क्यों आवश्यक है, जब एक संदर्भित कॉलम ( id) पहले से ही अद्वितीय होने की गारंटी है? जिस तरह से मैं इसे देखता हूं, नया अवरोध बेमानी होगा।

जवाबों:


11

यह डीबीएमएस की एक सीमा है - उन सभी में जहाँ तक मुझे पता है। और न केवल कॉलम जोड़ते समय, बल्कि स्तंभों को फेरते समय भी। हम एक है, तो UNIQUEपर बाधा (a1, a2)है, हम एक नहीं जोड़ सकते हैं FOREIGN KEYकि REFERENCES (a2, a1)जब तक कि वहाँ कि पर एक अद्वितीय बाधा है (a2, a1)कि अनिवार्य रूप से अनावश्यक है।

इसे फ़ीचर के रूप में जोड़ना बहुत मुश्किल नहीं होगा:

जब कोई UNIQUEबाधा होती है (a), तो किसी भी (a, b, c, ..., z)या (b,c, ...a, ...z)संयोजन की गारंटी भी होती है UNIQUE

या सामान्यीकरण:

जब कोई UNIQUEबाधा होती है (a1, a2, ..., aN), तो किसी भी (a1, a2, ..., aN, b1, b2, ..., bM)संयोजन या किसी पुनर्व्यवस्था की भी गारंटी होती है UNIQUE

ऐसा लगता है कि यह पूछा नहीं गया है या इसे लागू करने के लिए उच्च पर्याप्त प्राथमिकता नहीं माना गया है।

आप हमेशा अनुरोध कर सकते हैं - संबंधित चैनल में - लागू होने वाली सुविधा के लिए। या खुद भी इसे लागू करें, अगर DBMS ओपन सोर्स है, जैसे Postgres।


मुझे यकीन नहीं है कि यह काफी सरल होगा .. आंशिक सूचकांक, या पूर्ण मूल्यों के बारे में क्या? आदि .. अगर आप खुश हैं तो भी NULL अभी भी ठीक काम कर सकता है NULL != NULL। वैसे भी :) :)
जोशी बोडियो

@JoishiBodio मुझे नहीं लगता कि नल एक समस्या है। अद्वितीय बाधाओं को परिभाषित या अशक्त स्तंभों के रूप में अच्छी तरह से किया जा सकता है। डिफ़ॉल्ट यह है कि यदि किसी कॉलम में NULL है, तो बाधा को पारित कर दिया जाता है और पंक्ति को स्वीकार कर लिया जाता है।
ypercube y 16

दूसरे पर, अगर a1, a2, ... an अशक्त नहीं हैं और b1, b2, bM हैं तो हम समस्याओं में पड़ सकते हैं। लेकिन यह सुविधा निश्चित रूप से नॉट-न्यूबल कॉलम के लिए लागू की जा सकती है। संभवतः जो चिंताजनक है वह है दक्षता निहितार्थ।
ypercube y 17

मैं परिचित हूं UNIQUE INDEXकि कॉलम कहां हैं NULLABLE.. इसीलिए मैंने इसका उल्लेख किया है। :) लेकिन मैं सहमत हूँ - इस मामले में कि कोई NULLs (और या तो आंशिक सूचकांक नहीं है), यह संभवतः काफी सीधा है।
जोशी बोडियो

5

सामान्य रूप से विदेशी कुंजी (केवल मिश्रित नहीं) एक अन्य तालिका में कुछ प्रकार के एक UNIQUE कुंजी को इंगित करना चाहिए। यदि वे नहीं करते हैं, तो कोई संबंधपरक डेटा अखंडता नहीं होगी।

यह शिकायत है क्योंकि, जब आपके पास (आईडी) पर एक अद्वितीय कुंजी है .. तो आपके पास (आईडी, संख्या) पर एक अद्वितीय कुंजी नहीं है .. इस प्रकार, जहाँ तक DB का संबंध है, जोड़ी (आईडी, संख्या) अद्वितीय होने की गारंटी नहीं है। हमें, मनुष्य के रूप में, यह पता लगा सकते हैं कि यह अद्वितीय होगा, लेकिन मुझे यकीन है कि पोस्टग्रेज को स्मार्ट बनाने के लिए उन्हें अतिरिक्त कोड की आवश्यकता होगी, यह देखने के लिए कि "ओह हे .. आईडी अद्वितीय माना जाता है , इसलिए आईडी, संख्या भी अद्वितीय होनी चाहिए "।।

मुझे बहुत आश्चर्य होगा अगर उन्होंने उस कोड को जोड़ा जब आपको करना होगा कि समस्या को ठीक करने के लिए दो कॉलमों पर एक और अद्वितीय सूचकांक बनाएं।

बस स्पष्ट होने के लिए, उन्हें जो कोड जोड़ना होगा वह सिर्फ इस साधारण मामले में नहीं होगा ... इसे सभी मामलों को संभालना होगा, यहां तक ​​कि जहां विदेशी कुंजी 4+ कॉलम आदि पर है, मुझे यकीन है। तर्क काफी जटिल होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.