2012-06-05 18 views
8

क्या पोस्टग्रेएसक्यूएल में सशर्त रूप से विदेशी कुंजी जोड़ने के लिए यह संभव है?सशर्त पोस्टग्रेएसक्यूएल विदेशी कुंजी

कुछ की तरह: ALTER TABLE table1 ADD FOREIGN KEY (some_id) REFERENCES other_table WHERE some_id NOT IN (0,-1) AND some_id IS NOT NULL;

विशेष रूप से, मेरे संदर्भ तालिका सभी धनात्मक पूर्णांक है (1 +) लेकिन तालिका मैं विदेशी कुंजी जोड़ने की जरूरत है शून्य (0), अशक्त और नकारात्मक एक (शामिल कर सकते हैं करने के लिए -1) इसके बजाय, सभी का अर्थ कुछ अलग है।

नोट्स:

मैं पूरी तरह से पता है कि इस गरीब तालिका डिजाइन है कर रहा हूँ, लेकिन यह एक चतुर 10+ साल पहले बनाया जब सुविधाओं और संसाधनों हम है मौजूद नहीं था इस बिंदु पर उपलब्ध चाल था । यह प्रणाली सैकड़ों खुदरा स्टोर चला रही है इसलिए वापस जाकर इस बिंदु पर विधि को बदलने में महीनों लग सकते हैं जो हमारे पास नहीं है।

मैं ट्रिगर का उपयोग नहीं कर सकता, यह एक विदेशी कुंजी के साथ किया जाना चाहिए।

उत्तर

1

आप table1 जो साफ मान रखती है (अर्थात सब कुछ लेकिन 0 और -1) के लिए एक और "छाया" स्तंभ जोड़ सकते हैं। रेफरेंसियल अखंडता जांच के लिए इस कॉलम का प्रयोग करें। इस छाया कॉलम को table1 पर एक साधारण ट्रिगर द्वारा अपडेट/भर दिया गया है जो सभी मानों को लिखता है लेकिन 0 और -1 छाया कॉलम में लिखता है। 0 और -1 दोनों को null पर मैप किया जा सकता है।

फिर आपके पास संदर्भ अखंडता और आपका अपरिवर्तित मूल स्तंभ है। नकारात्मकता: आपके पास थोड़ा ट्रिगर और कुछ अनावश्यक डेटा भी है। लेकिन हां, यह एक विरासत स्कीमा का भाग्य है!

+0

जीनियस! आप सही हैं कि यह थोड़ा बदसूरत है, लेकिन डेटाबेस अभी भी खुद का प्रबंधन करता है, इसलिए यह चाल चलाना चाहिए! – trex005

+0

एएच, क्या आपने कभी पोस्टग्रेस स्रोत पर काम किया है? यह एक शानदार सुविधा हो सकती है जिसे आप दृश्यों के ठीक पीछे कर कर जोड़ सकते हैं। – trex005

+1

@ trex005: मैंने पीजी स्रोतों पर काम नहीं किया है। लेकिन हर समय हैकर की सूची पर झुकाव और फिर मेरी धारणा यह है कि इस तरह की एक सुविधा का स्वागत नहीं किया जाएगा। यदि आप _your_ उदाहरण को सामान्यीकृत करते हैं ('0' और' -1' के अलावा कुछ भी मिलान करें) और सभी संभावित मामलों को कवर करने वाले सामान्य वाक्यविन्यास के बारे में सोचें, तो आपको काफी जटिल वाक्य रचनात्मक निर्माण मिलेगा। पैमाने के दूसरी तरफ: ऐसा कुछ भी नहीं है जिसे आप पहले से मौजूद मौजूदा उपकरणों से नहीं कर सकते हैं। शुद्ध परिणाम: दुर्लभ संसाधन (डेवलपर समय/बजट) अन्य TODO वस्तुओं पर बेहतर भुगतान करेगा। लेकिन यह केवल मेरी छाप है। उनसे संपर्क करने के लिए स्वतंत्र हो जाओ। –

2

कम जवाब नहीं है, Postgres सशर्त विदेशी कुंजी नहीं है। कुछ विकल्प जो आप विचार कर सकते हैं वे हैं:

  1. बस एफके बाधा नहीं है। इस तर्क को डेटा एक्सेस लेयर में ले जाएं और रेफरेंसियल अखंडता के बिना लाइव रहें।
  2. कॉलम में NULL को अनुमति दें, जो कि एफके बाधा के साथ भी पूरी तरह मान्य है। फिर, 0 और -1 का अर्थ जो कुछ भी स्टोर करने के लिए एक और कॉलम का उपयोग करें।
  3. 0 और -1 के लिए संदर्भित तालिका में एक डमी पंक्ति जोड़ें। भले ही इसमें केवल फर्जी डेटा था, यह एफके बाधा को पूरा करेगा।

उम्मीद है कि इससे मदद मिलती है!

+1

ये काफी विकल्प मैं उम्मीद थी थे। उम्मीद है कि हम गलत हैं, मैं थोड़ी देर के लिए सवाल छोड़ दूंगा। :) – trex005

+2

विकल्प 4 हमेशा पोस्टग्रेस कोड को संशोधित कर रहा है, यह * ओपन सोर्स है जिसे आप जानते हैं :) –

+0

बहुत सच है ..... आपकी बोली क्या है? : ओ) – trex005

1

आपका आवश्यकता इस चेक बाधा के बराबर है:

create table t (a float check (a >= -1 and a = floor(a) or a is null)); 
+0

सच है, लेकिन एक चेक बाधा किसी अन्य तालिका में एक पंक्ति के अस्तित्व की जांच नहीं कर सकती है। –

+0

@ माइक क्रिस्टेनसेन सवाल यह है कि संदर्भित तालिका _ सभी सकारात्मक पूर्णांक (1 +) _ है। मुझे पता है कि यह असंभव है लेकिन मुझे लगता है कि उसका मतलब है कि इसमें एक निश्चित सीमा तक अंतराल के बिना सभी पूर्णांक हैं। यह जांच के लिए एक और शर्त के अतिरिक्त कवर किया जाएगा (एक <= एन)। –

+1

संभव है, मैंने अभी माना है कि ओपी वास्तव में एक वास्तविक विदेशी कुंजी चाहता था। –

0

यहां एक और संभावना है। तालिका के विभाजन को लागू करने के लिए पीजी विरासत का उपयोग फ्लैग कॉलम में +1 है और अन्यथा। (इसे बनाए रखने के लिए सामान्य नियम/ट्रिगर्स।) फिर केवल हैस_PLUS_ONE बाल तालिका और संदर्भित तालिका के बीच एफके संबंध रखें।

+0

पीजी विरासत का उपयोग लगभग किसी भी चीज़ के लिए सही समाधान नहीं है। वे बहुत सीमित और quirky हैं। – cliffordheath

0

आप इसे चेक बाधा और विदेशी कुंजी के साथ कार्यान्वित कर सकते हैं।

CREATE TABLE table1 (some_id INT, some_id_fkey INT REFERENCES other_table(other_id), CHECK (some_id IN (0,-1) OR some_id IS NOT DISTINCT FROM some_id_fkey)); 

(नहीं परीक्षण किया)

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