postgresql विदेशी कुंजी वाक्यविन्यास


122

मेरे पास 2 टेबल हैं जैसा कि आप नीचे दिए गए मेरे posgresql कोड में देखेंगे। पहली तालिका के छात्रों में 2 कॉलम होते हैं, एक छात्र_नाम के लिए और दूसरा छात्र_ जो प्राथमिक कुंजी है। परीक्षण नामक मेरी दूसरी तालिका में, इसमें 4 कॉलम होते हैं, एक व्यक्ति के लिए, एक व्यक्ति के लिए, एक विषय_नाम के लिए, फिर एक छात्र के लिए एक हिगिस्त स्कोर के साथ एक विषय में जो उच्चतम है। मैं अपने छात्रों की तालिका में student_id का उच्चतम संदर्भ बनाने की कोशिश कर रहा हूं। यह नीचे दिया गया कोड है, अगर वाक्यविन्यास सही है तो मुझे यकीन नहीं है:

CREATE TABLE students ( student_id SERIAL PRIMARY KEY,
                 player_name TEXT);

CREATE TABLE tests ( subject_id SERIAL,
                   subject_name,
                   highestStudent_id SERIAL REFERENCES students);

वाक्यविन्यास highestStudent_id SERIAL REFERENCES studentsसही है? क्योंकि मैंने एक दूसरे को देखा हैhighestStudent_id REFERENCES students(student_id))

कृपया Postgresql में विदेशी कुंजी बनाने का सही तरीका क्या होगा?


4
हाँ वाक्य रचना "सही" है। हालाँकि FK कॉलम को परिभाषित नहीं किया serialजाना चाहिए क्योंकि इसे परिभाषित किया जाना चाहिए integerserial"वास्तविक" डेटा प्रकार नहीं है, यह अनुक्रम से डिफ़ॉल्ट मान को पॉप्युलेट करने के लिए एक छोटा हाथ है
a_horse_with_no_name

यदि FK एक प्राथमिक कुंजी को संदर्भित करता है, तो किसी कॉलम की आवश्यकता नहीं है। यदि FK एक वैकल्पिक कुंजी को संदर्भित करता है, तो कॉलम की आवश्यकता होती है।
jarlh

1
आपकी विदेशी कुंजी तालिका "खिलाड़ियों" का संदर्भ देती है। आप नहीं दिखाई देते है "खिलाड़ियों" नाम की एक मेज।
माइक शेरिल 'कैट रिकॉल'

@ माईक शेरिल 'कैट रिकॉल सॉरी, मेरी ग़लती का मतलब मैंने सबसे ज्यादा स्टूडेंट_डिजिटल रेफरर्स छात्रों से लिया
हमजा

जवाबों:


249

इस तालिका को मानते हुए:

CREATE TABLE students 
( 
  student_id SERIAL PRIMARY KEY,
  player_name TEXT
);

एक विदेशी कुंजी को परिभाषित करने के चार अलग-अलग तरीके हैं (जब एक एकल स्तंभ पीके के साथ काम करते हैं) और वे सभी एक ही विदेशी कुंजी बाधा की ओर ले जाते हैं:

  1. लक्ष्य कॉलम का उल्लेख किए बिना इनलाइन:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
  2. लक्ष्य कॉलम का उल्लेख करने के लिए इनलाइन:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
  3. अंदर लाइन से बाहर create table:

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer, 
      constraint fk_tests_students
         foreign key (highestStudent_id) 
         REFERENCES students (student_id)
    );
  4. एक अलग alter tableबयान के रूप में:

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer
    );
    
    alter table tests 
        add constraint fk_tests_students
        foreign key (highestStudent_id) 
        REFERENCES students (student_id);

जो आप पसंद करते हैं वह स्वाद का मामला है। लेकिन आपको अपनी स्क्रिप्ट्स के अनुरूप होना चाहिए। पिछले दो कथन एकमात्र विकल्प हैं यदि आपके पास पीके को संदर्भित करने वाली विदेशी कुंजी है जिसमें एक से अधिक कॉलम हैं - तो आप उस मामले में FK "इनलाइन" को परिभाषित नहीं कर सकते हैं, जैसेforeign key (a,b) references foo (x,y)

केवल संस्करण 3) और 4) आपको एफके की कमी के लिए अपने नाम को परिभाषित करने की क्षमता देगा यदि आप पोस्टग्रेज से उत्पन्न सिस्टम को पसंद नहीं करते हैं।


serialडेटा प्रकार वास्तव में एक डेटा प्रकार नहीं है। यह सिर्फ एक शॉर्ट हैंड नोटेशन है जो किसी अनुक्रम से लिए गए कॉलम के लिए डिफ़ॉल्ट मान को परिभाषित करता है। इसलिए किसी भी स्तंभ को संदर्भित एक स्तंभ के रूप में परिभाषित serialउचित आधार प्रकार का उपयोग कर परिभाषित किया जाना चाहिए integer(या bigintके लिए bigserialकॉलम)


यह लिंक ( postgresqltutorial.com/postgresql-foreign-key ) एक और तरीका बताता है कि आपने जो कहा वह केवल 3 और 4 में 'बाधा' कमांड के साथ किया जा सकता है। इसके अलावा, FK से पहले FOREIGN KEY लगाने के बारे में क्या? ऐसा लगता है कि जब हम ऐसा करते हैं, तो हमें चर प्रकार की घोषणा करने की आवश्यकता नहीं है?
शब्दफिरवाइज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.