2010-12-23 14 views
6

में सशर्त विदेशी कुंजी मैं PartyChannel निम्नलिखित कॉलमएसक्यूएल

ID, ChannelID, ChannelType 

ChannelID भंडार MailID या PhoneID या EmailID होने के रूप में ChannelType के आधार पर एक मेज कहा जाता है।

तो मैं चैनल चैपल के आधार पर पार्टी चैनल और सभी तीन तालिकाओं (मेल, ईमेल और फोन) के बीच एक विदेशी कुंजी कैसे बना सकता हूं।

+3

MailID, PhoneID, EmailId तीन अलग डोमेन हैं और नहीं, एक भी चैनल-स्तंभ का उपयोग नहीं मॉडलिंग की जानी चाहिए कर सकते हैं। यह मौलिक सामान है। – onedaywhen

उत्तर

4

AFAIK, आप मानक विदेशी कुंजी के साथ ऐसा नहीं कर सकते हैं। हालांकि, आप ट्रिगर्स का उपयोग कर डेटा अखंडता सुनिश्चित करने में मदद के लिए कुछ लागू कर सकते हैं। अनिवार्य रूप से, ट्रिगर संदर्भित तालिका पर "विदेशी कुंजी" की उपस्थिति की जांच करेगा - वह मान जो उपस्थित होना चाहिए - जब भी संदर्भ तालिका में कोई सम्मिलित या अद्यतन होता है। इसी तरह, संदर्भित तालिका से हटाए जाने वाले ट्रिगर में एक ट्रिगर हो सकता है जो संदर्भित तालिका पर रिकॉर्ड्स की जांच करता है जो हटाए जाने वाले कुंजी का उपयोग करता है।

अपडेट: हालांकि मैं "उत्तर" के लिए सही गया, मैं @onedaywhen द्वारा छोड़ी गई टिप्पणी से सहमत हूं कि यह वास्तव में एक डिज़ाइन-कारण समस्या है जो आपको शायद आपके डिज़ाइन पर पुनर्विचार कर दे। यही है, आपके पास तीन तालिकाओं का संदर्भ देने वाले एक कॉलम के बजाय तीन अलग-अलग कॉलम होना चाहिए। जब आप एक भर जाते हैं तो आप केवल दो कॉलम को छोड़ देंगे, बदले में, आप मानक विदेशी कुंजी का उपयोग करने देंगे। कोई चिंता यह है कि यह "बहुत अधिक जगह का उपयोग" मूर्खतापूर्ण है; यह समयपूर्व अनुकूलन के गंभीर मामले का प्रतिनिधित्व करता है - यह सिर्फ मामला नहीं है।

7

आप केस स्टेटमेंट के साथ PERSISTED COMPUTED कॉलम का उपयोग कर सकते हैं लेकिन अंत में, यह आपको ओवरहेड के अलावा कुछ भी नहीं खरीदता है।

सबसे अच्छा समाधान उन्हें शुरू करने के लिए तीन अलग-अलग मानों के रूप में मॉडल करना होगा।

CREATE TABLE Mails (MailID INTEGER PRIMARY KEY) 
CREATE TABLE Phones (PhoneID INTEGER PRIMARY KEY) 
CREATE TABLE Emails (EmailID INTEGER PRIMARY KEY) 

CREATE TABLE PartyChannel (
    ID INTEGER NOT NULL 
    , ChannelID INTEGER NOT NULL 
    , ChannelType CHAR(1) NOT NULL 
    , MailID AS (CASE WHEN [ChannelType] = 'M' THEN [ChannelID] ELSE NULL END) PERSISTED REFERENCES Mails (MailID) 
    , PhoneID AS (CASE WHEN [ChannelType] = 'P' THEN [ChannelID] ELSE NULL END) PERSISTED REFERENCES Phones (PhoneID) 
    , EmailID AS (CASE WHEN [ChannelType] = 'E' THEN [ChannelID] ELSE NULL END) PERSISTED REFERENCES Emails (EmailID) 
) 

अस्वीकरण

सिर्फ इसलिए कि आप मतलब यह नहीं है कर सकते हैं करना चाहिए।

+0

यह बहुत जंगली है। क्या यह सभी प्रमुख एसक्यूएल कार्यान्वयन में काम करता है? –

+0

@ मार्क: यह SQL सर्वर 2005 और 2008 के साथ काम करता है। इसके अलावा, मुझे ईमानदारी से कोई जानकारी नहीं है, यह एक अच्छा मानसिक व्यायाम था। एक अस्वीकरण शायद क्रम में हो सकता है: * सिर्फ इसलिए कि आप इसका मतलब यह नहीं कर सकते कि आपको चाहिए! * –

+0

यह SQL सर्वर में काम करता है हालांकि आपका चैनल टाइप एक int के बजाय एक char या varchar होना चाहिए। दोबारा - +1 - धन्यवाद। बहुत रोचक और असामान्य सामान। मैं अभी भी @onedaywhen से सहमत हूं कि यह एक अच्छा डिज़ाइन नहीं है, लेकिन मैंने आपके द्वारा प्रदान की गई ऑफ़बीट एसक्यूएल में सबक की सराहना की है! –

4

उप-प्रकार Email, Mail, PhoneChannel पर।

alt text

+0

यह जेन-स्पेक पैटर्न है, जैसा कि एक रिलेशनल मॉडल में दर्शाया गया है। चित्र अच्छी तरह से चाबियाँ दिखाता है। बहुत बढ़िया। –