PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

दो प्राथमिक कुंजी को इंगित करने वाली विदेशी कुंजी कैसे प्राप्त करें?

FK बाधाओं के लिए नियम

शीर्षक में और अपने पाठ के अंत में प्रश्न का उत्तर देने के लिए:

"मैं अब भी जानना चाहूंगा कि कैसे एक विदेशी कुंजी दो प्राथमिक कुंजियों को संदर्भित करती है।"

यह असंभव है।

  • एक FOREIGN KEY बाधा केवल एक . को इंगित कर सकती है तालिका और प्रत्येक तालिका में केवल एक हो सकता है PRIMARY KEY कोड> बाधा।

  • या आपके पास एकाधिक हो सकता है FOREIGN KEY एक . को संदर्भित करने वाले एक ही कॉलम पर बाधाएं PRIMARY KEY प्रत्येक (अलग) तालिका का। (शायद ही कभी उपयोगी।)

हालांकि , एक एकल PK या FK कर सकते हैं कई कॉलमों को फैलाना।
और एक FK लक्ष्य में किसी भी स्पष्ट रूप से परिभाषित अद्वितीय (सेट) कॉलम को संदर्भित कर सकता है, न कि केवल PK को। मैनुअल:

एक बहुस्तंभ PK या UNIQUE बाधा को केवल मेल खाने वाले कॉलम प्रकारों के साथ एक बहु-स्तंभ FK बाधा द्वारा संदर्भित किया जा सकता है।

आप क्या पूछते हैं

चूंकि इसे UNIQUE की कॉलम सूची में एक ही कॉलम को एक से अधिक बार उपयोग करने की अनुमति नहीं है या PRIMARY KEY बाधा, एक FOREIGN KEY की लक्ष्य सूची एक ही कॉलम का एक से अधिक बार उपयोग भी नहीं कर सकते हैं। लेकिन हमें स्रोत . में एक ही कॉलम को एक से अधिक बार उपयोग करने से रोकने के लिए कुछ भी नहीं है सूची। आप जो पूछ रहे हैं उसे लागू करने की क्षमता यहां निहित है (लेकिन शायद इसका मतलब यह नहीं था):

"team_statistics में तालिका team_statistics.team_id एक विदेशी कुंजी होनी चाहिए जो matches.team_id . का संदर्भ देती हो और matches.team_id1 "

(team_id, team_id1) . का संयोजन तालिका में matches परिभाषित करने की आवश्यकता होगी UNIQUE . team_statistics.team_id . में मान team = team1 वाले मामलों तक ही सीमित रहेगा तालिका में matches तार्किक परिणाम के रूप में:

ALTER TABLE matches
ADD constraint matches_teams_groups_uni UNIQUE (team_id, team_id1);

ALTER TABLE team_statistics
  ADD constraint team_statistics_team_group fkey
  FOREIGN KEY (team_id, team_id)  -- same column twice!
  REFERENCES matches(team_id, team_id1);

यहां तक ​​कि कुछ सेटअप के लिए भी सही हो सकता है, लेकिन आपके लिए नहीं।

शायद आपको क्या चाहिए

मेरा शिक्षित अनुमान है कि आप कुछ इस तरह चाहते हैं:

(match_id, team_id) तालिका में team_statistics एक विदेशी कुंजी होनी चाहिए जो या तो references का संदर्भ देती हो (match_id, team_id) या (match_id, team_id1) तालिका में matches .

और यह एफके बाधाओं और सिर्फ दो तालिकाओं के साथ संभव नहीं है। आप कर सकते थे एक CHECK का दुरुपयोग करें एक नकली IMMUTABLE . के साथ बाधा कार्य करें और इसे NOT VALID make बनाएं . इस उत्तर में अध्याय "चेक बाधा के साथ सस्ता" देखें:

लेकिन यह उन्नत चालबाजी और कम विश्वसनीय है। यहां मेरा सुझाव नहीं है, इसलिए मैं विस्तार से नहीं बता रहा हूं। मेरा सुझाव है कि सामान्य करें आपकी स्कीमा उपयोगी तरीके से, जैसे:

CREATE TABLE team (team_id serial PRIMARY KEY
                 , team text NOT NULL UNIQUE);     -- add more attributes for team

CREATE TABLE match (match_id serial PRIMARY KEY);  -- add more attributes for match

CREATE TABLE match_team (
   match_id  int  REFERENCES match  -- short notation for FK
 , team_id   int  REFERENCES team
 , home boolean                     -- TRUE for home team, FALSE for away team
 , innings_score int
 -- more attributes of your original "team_statistics"
 , PRIMARY KEY (match_id, team_id, home)  -- !!! (1st column = match_id)
 , UNIQUE (team_id, match_id)             -- optional, (1st column = team_id)
);

home मैच की घरेलू टीम को चिह्नित करता है, लेकिन पीके में शामिल करके, प्रति मैच अधिकतम दो टीमों तक भी सीमित कर देता है . (पीके कॉलम परिभाषित हैं NOT NULL परोक्ष रूप से।)

वैकल्पिक UNIQUE (team_id, match_id) . पर प्रतिबंध टीमों को अपने खिलाफ खेलने से रोकता है। इंडेक्स कॉलम के उल्टे अनुक्रम का उपयोग करके (नियम लागू करने के लिए अप्रासंगिक) यह पीके के लिए एक इंडेक्स पूरक भी प्रदान करता है, जो आमतौर पर उपयोगी भी होता है। देखें:

आप कर सकते थे एक अलग match_team_statistics add जोड़ें , लेकिन यह match_team . के लिए केवल एक वैकल्पिक 1:1 एक्सटेंशन होगा अभी व। वैकल्पिक रूप से बस match_team में कॉलम जोड़ें ।

मैं दृश्य जोड़ सकता हूं विशिष्ट प्रदर्शनों के लिए, जैसे:

CREATE VIEW match_result AS
SELECT m.match_id
     , concat_ws(' : ', t1.team, t2.team) AS home_vs_away_team
     , concat_ws(' : ', mt1.innings_score, mt2.innings_score) AS result
FROM   match           m
LEFT   JOIN match_team mt1 ON mt1.match_id = m.match_id AND mt1.home
LEFT   JOIN team       t1  ON t1.team_id = mt1.team_id
LEFT   JOIN match_team mt2 ON mt2.match_id = m.match_id AND NOT mt2.home
LEFT   JOIN team       t2  ON t2.team_id = mt2.team_id;

बुनियादी सलाह:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL में पिवट टेबल कैसे बनाएं

  2. PostgreSQL बहु-स्तंभ आंशिक अनुक्रमणिका में डेटाटाइम बाधा जोड़ें

  3. स्लीक एंड बोनसीपी:org.postgresql.util.PSQLException:FATAL:क्षमा करें, बहुत से क्लाइंट पहले से ही त्रुटि कर रहे हैं

  4. PostgreSQL डेटाबेस को दूसरे सर्वर पर कॉपी करना

  5. सेलेक्ट क्लॉज में एकाधिक सेट-रिटर्निंग फ़ंक्शंस के लिए अपेक्षित व्यवहार क्या है?