दिलचस्प पोस्ट
आप VBA कोड के समय का परीक्षण कैसे करते हैं? SQL सर्वर – संग्रहित प्रक्रिया से चुनें मैं T-SQL संग्रहीत कार्यविधि में वैकल्पिक पैरामीटर कैसे उपयोग कर सकता हूं? Socket.io के साथ PHP का उपयोग करना Iframe में google.com कैसे दिखाना है? एकाधिक, अनुक्रमिक लाने () वादा निर्धारित करें कि क्या कोई तत्व jQuery के साथ एक सीएसएस वर्ग है वाइल्डकार्ड के साथ नया जेनेरिक ऑब्जेक्ट बनाना पेस्ट इनपुट पकड़ो C ++ में नेस्टेड प्रकार / कक्षाओं की अग्रेषित घोषणा यह क्यों असंभव है कि आईओ के प्रयास किए बिना, यह पता लगाने के लिए कि टीसीपी सॉकेट को सहकर्मी ने शानदार ढंग से बंद कर दिया था? जावा में एक कस्टम अपवाद प्रकार कैसे बनाऊँ? जब Android ऐप पृष्ठभूमि पर जाता है और अग्रभूमि पर वापस आ जाता है, तो यह कैसे पता लगा सकता है NSAttributedString के साथ स्ट्रिंग रंग बदलें? रूबी में मैं एचटीएमएल संस्थाओं को एनकोड / व्याख्या कैसे करूं?

बहुलोफिक एसोसिएशन में आप एक विदेशी कुंजी क्यों नहीं हो सकते?

एक बहुलक संघ में क्यों कोई विदेशी कुंजी नहीं हो सकती, जैसे कि रेल मॉडल के रूप में नीचे दर्शाया गया है?

class Comment < ActiveRecord::Base belongs_to :commentable, :polymorphic => true end class Article < ActiveRecord::Base has_many :comments, :as => :commentable end class Photo < ActiveRecord::Base has_many :comments, :as => :commentable #... end class Event < ActiveRecord::Base has_many :comments, :as => :commentable end 

वेब के समाधान से एकत्रित समाधान "बहुलोफिक एसोसिएशन में आप एक विदेशी कुंजी क्यों नहीं हो सकते?"

एक विदेशी कुंजी को केवल एक अभिभावक तालिका संदर्भित करना चाहिए। यह SQL सिंटैक्स और रिलेशनल सिद्धांत दोनों के लिए मौलिक है।

एक पॉलीमॉर्फिक एसोसिएशन तब होता है जब एक दिया स्तंभ दो या दो से अधिक पैरेंट तालिकाओं के संदर्भ में हो सकता है। कोई रास्ता नहीं है कि आप SQL में उस बाधा को घोषित कर सकते हैं

पॉलीमॉर्फिक एसोसिएशन डिजाइन रिलेशनल डेटाबेस डिजाइन के नियमों को तोड़ते हैं। मैं इसे उपयोग करने की अनुशंसा नहीं करता

कई विकल्प हैं:

  • अनन्य आर्क: एकाधिक विदेशी कुंजी कॉलम बनाएँ, प्रत्येक एक माता पिता को संदर्भित करता है। लागू करें कि इन विदेशी कुंजियों में से कोई भी गैर-नल हो सकता है

  • रिवर्स रिवर्स: तीन सेज़-टू-टेबल का उपयोग करें, प्रत्येक संदर्भ टिप्पणियाँ और संबंधित माता-पिता

  • कंक्रीट निडरता: अंतर्निहित "टिप्पणी करने योग्य" सुपरक्लास के बजाय, एक वास्तविक तालिका बनाएं, जिसमें आपके प्रत्येक पैरेंट टेबल का संदर्भ होता है। उसके बाद आपकी टिप्पणियां उस सुपरटेबल के लिए लिंक करें छद्म-रेल कोड निम्न जैसा होगा (मैं रेल उपयोगकर्ता नहीं हूं, इसलिए इसे दिशानिर्देश के रूप में नहीं मानना, शाब्दिक कोड नहीं):

     class Commentable < ActiveRecord::Base has_many :comments end class Comment < ActiveRecord::Base belongs_to :commentable end class Article < ActiveRecord::Base belongs_to :commentable end class Photo < ActiveRecord::Base belongs_to :commentable end class Event < ActiveRecord::Base belongs_to :commentable end 

मैं SQL में मेरी प्रस्तुति प्रैक्टिकल ऑब्जेक्ट-ओरिएंटेड मॉडेल्स में पॉलिमॉर्फ़िक एसोसिएशनों को भी कवर करता हूं, और मेरी किताब एसक्यूएल एंटिपेटर्नः डाटाबेस प्रोग्रामिंग के नुकसान से बचना


अपनी टिप्पणी पुनः: हां, मुझे पता है कि एक और स्तंभ है जो तालिका के नाम को नोट करता है जो कि विदेशी कुंजी माना जाता है। यह डिज़ाइन SQL में विदेशी कुंजियों द्वारा समर्थित नहीं है

उदाहरण के लिए, यदि आप उस Comment लिए मूल तालिका के नाम के रूप में टिप्पणी और नाम "वीडियो" डालते हैं, तो क्या होता है? "वीडियो" नामक कोई तालिका मौजूद नहीं है। क्या प्रविष्टि को एक त्रुटि से निरस्त किया जाना चाहिए? क्या बाधा का उल्लंघन किया जा रहा है? आरडीबीएमएस कैसे जानते हैं कि इस स्तंभ को मौजूदा तालिका का नाम देना है? यह केस-असंवेदनशील तालिका के नामों को कैसे नियंत्रित करता है?

इसी तरह, यदि आप Events टेबल छोड़ते हैं, लेकिन आपके पास ऐसे Comments में पंक्तियां हैं जो घटनाओं को अपने माता-पिता के रूप में दर्शाती हैं, तो परिणाम क्या होगा? क्या ड्रॉप टेबल को निरस्त किया जाना चाहिए? Comments में पंक्तियों अनाथ होना चाहिए? क्या वे किसी अन्य मौजूदा तालिका का संदर्भ बदल सकते हैं जैसे Articles ? Articles ओर इशारा करते समय Events को इंगित करने वाले आईडी मानों का क्या मतलब है?

ये दुविधाएं इस तथ्य की वजह से हैं कि मेटाडाटा (एक टेबल नाम) को संदर्भित करने के लिए पोलीमॉर्फिक एसोसिएशन डेटा (जैसे स्ट्रिंग मान) का उपयोग करने पर निर्भर करता है। यह SQL द्वारा समर्थित नहीं है डेटा और मेटाडेटा अलग हैं


मेरे "कंक्रीट प्रत्याशित" प्रस्ताव के आसपास मेरे सिर को लपेटने में मुझे एक कठिन समय आ रहा है

  • एक असली एसक्यूएल तालिका के रूप में Commentable परिभाषित करें, न कि आपके रेल मॉडल की परिभाषा में एक विशेषण। कोई अन्य स्तंभ आवश्यक नहीं हैं

     CREATE TABLE Commentable ( id INT AUTO_INCREMENT PRIMARY KEY ) TYPE=InnoDB; 
  • तालिका, Photos , और Events को परिभाषित करने के लिए "सबक्लासेस" के रूप में परिभाषित करें, उनकी प्राथमिक कुंजी बनाकर एक विदेशी कुंजी संदर्भित भी हो सकती है

     CREATE TABLE Articles ( id INT PRIMARY KEY, -- not auto-increment FOREIGN KEY (id) REFERENCES Commentable(id) ) TYPE=InnoDB; -- similar for Photos and Events. 
  • Comments तालिका को परिभाषित करने के लिए एक विदेशी कुंजी के साथ परिभाषित करें

     CREATE TABLE Comments ( id INT PRIMARY KEY AUTO_INCREMENT, commentable_id INT NOT NULL, FOREIGN KEY (commentable_id) REFERENCES Commentable(id) ) TYPE=InnoDB; 
  • जब आप एक Article (उदाहरण के लिए) बनाना चाहते हैं, तो आपको Commentable भी एक नई पंक्ति बनाना चाहिए। तो भी Photos और Events के लिए

     INSERT INTO Commentable (id) VALUES (DEFAULT); -- generate a new id 1 INSERT INTO Articles (id, ...) VALUES ( LAST_INSERT_ID(), ... ); INSERT INTO Commentable (id) VALUES (DEFAULT); -- generate a new id 2 INSERT INTO Photos (id, ...) VALUES ( LAST_INSERT_ID(), ... ); INSERT INTO Commentable (id) VALUES (DEFAULT); -- generate a new id 3 INSERT INTO Events (id, ...) VALUES ( LAST_INSERT_ID(), ... ); 
  • जब आप कोई Comment बनाना चाहते हैं, तो उसमें एक मूल्य का उपयोग करें जो टिप्पणीयोग्य में मौजूद है।

     INSERT INTO Comments (id, commentable_id, ...) VALUES (DEFAULT, 2, ...); 
  • जब आप किसी दिए गए Photo की टिप्पणियों को क्वेरी करना चाहते हैं, तो कुछ जुड़ें:

     SELECT * FROM Photos p JOIN Commentable t ON (p.id = t.id) LEFT OUTER JOIN Comments c ON (t.id = c.commentable_id) WHERE p.id = 2; 
  • जब आपके पास केवल एक टिप्पणी का आईडी होता है और आप यह जानना चाहते हैं कि कौन सी टिप्पणी योग्य संसाधन यह टिप्पणी के लिए है। इसके लिए, आप पा सकते हैं कि टिप्पणी करने योग्य तालिका के लिए यह संदर्भ कौन सा संसाधन संदर्भित करता है।

     SELECT commentable_id, commentable_type FROM Commentable t JOIN Comments c ON (t.id = c.commentable_id) WHERE c.id = 42; 

    फिर आपको संबंधित संसाधन तालिका (फ़ोटो, आलेख, आदि) से डेटा प्राप्त करने के लिए एक दूसरी क्वेरी चलाने की आवश्यकता होगी, जो commentable_type खोज के बाद जो तालिका में शामिल हो आप इसे एक ही प्रश्न में नहीं कर सकते, क्योंकि एसक्यूएल के लिए आवश्यक है कि तालिकाओं को स्पष्ट रूप से नाम दिया गया हो; आप एक ही क्वेरी में डेटा परिणामों से निर्धारित तालिका में शामिल नहीं हो सकते

बेशक, इन चरणों में से कुछ रेल द्वारा उपयोग किए जाने वाले सम्मेलनों को तोड़ते हैं। लेकिन उचित संबंधपरक डेटाबेस डिजाइन के संबंध में रेल सम्मेलनों गलत हैं।

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

 CREATE FUNCTION delete_related_brokerage_subscribers() RETURNS trigger AS $$ BEGIN DELETE FROM subscribers WHERE referrer_type = 'Brokerage' AND referrer_id = OLD.id; RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE TRIGGER cascade_brokerage_subscriber_delete AFTER DELETE ON brokerages FOR EACH ROW EXECUTE PROCEDURE delete_related_brokerage_subscribers(); CREATE FUNCTION delete_related_agent_subscribers() RETURNS trigger AS $$ BEGIN DELETE FROM subscribers WHERE referrer_type = 'Agent' AND referrer_id = OLD.id; RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE TRIGGER cascade_agent_subscriber_delete AFTER DELETE ON agents FOR EACH ROW EXECUTE PROCEDURE delete_related_agent_subscribers(); 

मेरे कोड में brokerages तालिका में एक रिकॉर्ड या agents तालिका में एक रिकार्ड subscribers तालिका में एक रिकॉर्ड से संबंधित हो सकता है।