2010-05-30 15 views
7

मैं एक सास अवधारणा के लिए बहु-किराये डेटाबेस स्कीमा डिज़ाइन देख रहा हूं। यह एएसपी.नेट एमवीसी -> ईएफ होगा, लेकिन यह इतना महत्वपूर्ण नहीं है।इकाई फ्रेमवर्क और बहु-किरायेदारी डेटाबेस डिजाइन

नीचे आप एक उदाहरण डेटाबेस स्कीमा (किरायेदार कंपनी होने) देख सकते हैं। कंपनी आईडी को पूरे स्कीमा में दोहराया गया है और प्राथमिक कुंजी दोनों प्राकृतिक कुंजी, साथ ही किरायेदार आईडी पर रखा गया है।

  • संबंध 'FK_Order_Customer' विदेशी चाबियों का सेट का उपयोग करता: जब मैं इकाई मॉडल फ़ाइल में तालिकाओं (Model1.edmx) जोड़ने

    इकाई की रूपरेखा में इस स्कीमा Plugging निम्न त्रुटियों देता है '{ग्राहक आईडी, कंपनीआईडी}' जो तालिका 'ऑर्डर' के प्राथमिक कुंजी '{OrderId, CompanyId}' के सेट में आंशिक रूप से निहित हैं। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल में मैप किए जाने के लिए प्राथमिक कुंजी के सेट में पूरी तरह निहित नहीं होना चाहिए।

  • रिश्ते 'FK_OrderLine_Customer' विदेशी कुंजी '{CustomerId, CompanyId}' के सेट का उपयोग करता है जो आंशिक रूप से 'ऑर्डरलाइन' तालिका के प्राथमिक कुंजी '{OrderLineId, CompanyId}' के सेट में निहित है। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल में मैप किए जाने के लिए प्राथमिक कुंजी के सेट में पूरी तरह निहित नहीं होना चाहिए।
  • रिश्ते 'FK_OrderLine_Order' विदेशी कुंजी '{OrderId, CompanyId}' के सेट का उपयोग करता है जो आंशिक रूप से 'ऑर्डरलाइन' तालिका के प्राथमिक कुंजी '{OrderLineId, CompanyId}' के सेट में निहित है। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल में मैप किए जाने के लिए प्राथमिक कुंजी के सेट में पूरी तरह निहित नहीं होना चाहिए।
  • रिश्ते 'FK_Order_Customer' विदेशी कुंजी '{ग्राहक आईडी, कंपनीआईडी}' के सेट का उपयोग करता है जो आंशिक रूप से तालिका 'ऑर्डर' के प्राथमिक कुंजी '{OrderId, CompanyId}' के सेट में निहित है। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल में मैप किए जाने के लिए प्राथमिक कुंजी के सेट में पूरी तरह निहित नहीं होना चाहिए।
  • रिश्ते 'FK_OrderLine_Customer' विदेशी कुंजी '{CustomerId, CompanyId}' के सेट का उपयोग करता है जो आंशिक रूप से 'ऑर्डरलाइन' तालिका के प्राथमिक कुंजी '{OrderLineId, CompanyId}' के सेट में निहित है। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल में मैप किए जाने के लिए प्राथमिक कुंजी के सेट में पूरी तरह निहित नहीं होना चाहिए।
  • रिश्ते 'FK_OrderLine_Order' विदेशी कुंजी '{OrderId, CompanyId}' के सेट का उपयोग करता है जो आंशिक रूप से 'ऑर्डरलाइन' तालिका के प्राथमिक कुंजी '{OrderLineId, CompanyId}' के सेट में निहित है। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल में मैप किए जाने के लिए प्राथमिक कुंजी के सेट में पूरी तरह निहित नहीं होना चाहिए।
  • रिश्ते 'FK_OrderLine_Product' विदेशी कुंजी '{ProductId, CompanyId}' के सेट का उपयोग करता है जो आंशिक रूप से 'ऑर्डरलाइन' तालिका के प्राथमिक कुंजी '{OrderLineId, CompanyId}' के सेट में निहित है। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल में मैप किए जाने के लिए प्राथमिक कुंजी के सेट में पूरी तरह निहित नहीं होना चाहिए।

प्रश्न दो भागों में है:

  1. मेरी डेटाबेस डिजाइन गलत है? क्या मुझे इन यौगिक प्राथमिक कुंजी से बचना चाहिए? मैं मौलिक स्कीमा डिज़ाइन (फ्रैज्ड मस्तिष्क सिंड्रोम) के संबंध में अपनी स्वच्छता पर सवाल उठा रहा हूं। कृपया 'आदर्शीकृत' स्कीमा का सुझाव देने के लिए स्वतंत्र महसूस करें।
  2. वैकल्पिक रूप से, यदि डेटाबेस डिज़ाइन सही है, तो क्या ईएफ कुंजी से मिलान करने में असमर्थ है क्योंकि यह इन विदेशी कुंजी को संभावित गलत कॉन्फ़िगर किए गए 1: 1 रिश्तों (गलत तरीके से) के रूप में समझता है? इस मामले में, क्या यह एक ईएफ बग है और मैं इसके आसपास कैसे काम कर सकता हूं?

Multi-tenancy database schema http://i46.tinypic.com/23si52u.png

+0

यदि मैं समग्र प्राथमिक कुंजी को हटाता हूं और केवल प्राकृतिक कुंजी (ProductId, OrderId, CustomerId, OrderLineId) का उपयोग करता हूं तो ईएफ त्रुटि दूर हो जाती है। हालांकि, मुझे यकीन नहीं है कि क्या यह सिर्फ कालीन के नीचे बकवास को फेंक रहा है! – Junto

+0

प्राथमिक आवश्यकताओं को दो आवश्यकताओं को पूरा करने की आवश्यकता है। सबसे पहले, यह अद्वितीय होना चाहिए। दूसरा, सामान्यीकरण के लिए, सभी गैर-महत्वपूर्ण तत्व प्राथमिक कुंजी पर पूरी तरह से निर्भर होना चाहिए। आपकी कुछ यौगिक कुंजी सामान्य रूप से सामान्य रूप से सामान्य रूप से तोड़ती हैं, क्योंकि ऐसा लगता है कि आपकी यौगिक कुंजी का एक घटक यौगिक कुंजी के दूसरे भाग पर निर्भर है। यह यौगिक कुंजी के साथ एक बड़ा जोखिम है। तो अपनी चिंता का जवाब देने के लिए, नहीं, यह * नहीं * कालीन के नीचे सिर्फ झुकाव बकवास है! –

उत्तर

4

एफई के त्रुटि संदेशों में से एक त्वरित स्कैन, यह स्पष्ट रूप से जिस तरह से आप यौगिक कुंजी सेट कर रहे हैं पसंद नहीं है, और मैं यह शायद सही दिशा में परोक्ष दबाव डाल रहा है लगता है। अपनी प्राथमिक कुंजी को अद्वितीय बनाने के लिए फिर से कुछ विचार दें। क्या ऑर्डर आईडी अकेले अद्वितीय नहीं है, बिना कंपनी आईडी के? क्या एक उत्पाद आईडी बिना किसी कंपनी आईडी के अद्वितीय है? एक ऑर्डरलाइन निश्चित रूप से एक कंपनी आईडी के बिना अद्वितीय होना चाहिए, क्योंकि ऑर्डरलाइन केवल एक ही आदेश से जुड़ी होनी चाहिए।

यदि आपको वास्तव में इन सभी के लिए कंपनी आईडी की आवश्यकता है, जिसका शायद मतलब है कि कंपनी उत्पाद में आपको उत्पाद आईडी और ऑर्डर आईडी के साथ आपूर्ति कर रही है, तो आप एक अलग दिशा तय कर सकते हैं, और अपनी प्राथमिक कुंजी उत्पन्न नहीं कर सकते हैं डेटा के लिए आंतरिक। बस अपनी प्राथमिक कुंजी के लिए एक ऑटो-वृद्धि कॉलम सेट अप करें, और इन्हें आंतरिक ऑर्डर आईडी, ऑर्डरलाइन, उत्पाद आईडी, कंपनीआईडी ​​इत्यादि दें। उस बिंदु पर ऑर्डरलाइन को ग्राहक के ऑर्डर आईडी या कंपनीआईडी ​​की आवश्यकता नहीं होगी; आदेश का विदेशी कुंजी संदर्भ इसका प्रारंभिक बिंदु होगा। (और ग्राहक आईडी को ऑर्डर लाइन का गुण कभी नहीं होना चाहिए; यह ऑर्डर की विशेषता है, ऑर्डर लाइन नहीं।)

कंपाउंड कुंजी सिर्फ गन्दा हैं। उनके बिना मॉडल को डिजाइन करने का प्रयास करें, और देखें कि यह चीजों को सरल बनाता है या नहीं।

+0

मैं यौगिक कुंजी पर सहमत हूं। मुझे यह भी यकीन नहीं है कि मैंने उन्हें पहली जगह क्यों जोड़ा! देर रात प्रोग्रामिंग मेरे लिए कभी अच्छा विचार नहीं है। – Junto

+0

मैं ईजेबी की बजाय साइलन बिल्ली का जवाब देने जा रहा हूं, मुख्य रूप से क्योंकि उसने मेरी विचार प्रक्रियाओं को ट्रिगर किया क्योंकि मैंने पहली जगह में गठबंधन कुंजी क्यों जोड़ दी थी (गलत तरीके से)। दोनों धन्यवाद। – Junto

+0

मैं सहमत नहीं हूँ। त्रुटि का कारण वह फ़ील्ड है जो जुंटो ने तब तक उपयोग नहीं किया जब वह संबंधों को बनाते हैं। प्रत्येक तालिका में कंपनी आईडी बहु-किरायेदार साइटों में बहुत मदद करता है। –

2

मुझे लगता है कि प्रत्येक तालिका में कंपनी नंबर संग्रहित करने से आपको मदद करने से अधिक नुकसान पहुंचा रहा है। मैं समझ सकता हूं कि आप ऐसा क्यों करना चाहते हैं (प्रोग्रामर/डीबीए के रूप में आप किसी भी तालिका में जा सकते हैं और 'देखें' कौन सा डेटा सांत्वना देता है), लेकिन यह डेटाबेस को स्थापित करने के तरीके में हो रहा है जिस तरह से होना चाहिए।

यौगिक कुंजी से बचें और आपका डिज़ाइन पूरी तरह से सरल हो जाता है।

+0

सहमत हुए। कंपाउंड कुंजी binned। – Junto

2

मुझे लगता है कि त्रुटि डिज़ाइन में नहीं है। ईएफ में नहीं है। एसक्यूएल सर्वर संबंधों में है।

एफई संदेश पढ़ें:

संबंध 'FK_Order_Customer' विदेशी कुंजी के सेट का उपयोग करता '{ग्राहक आईडी, CompanyId}' कि आंशिक रूप से प्राथमिक कुंजियों का सेट में निहित हैं '{ ऑर्डर आईडी, कंपनीआईडी} ' तालिका' ऑर्डर '। विदेशी कुंजी का सेट प्राथमिक कुंजी के सेट प्राथमिक कुंजी के सेट में पूरी तरह निहित होना चाहिए, या किसी मॉडल पर मैप किए जाने के लिए प्राथमिक कुंजी के सेट में निहित पूरी तरह से निहित नहीं होना चाहिए।

त्रुटि

वास्तव में आदेश और ग्राहक उपयोग केवल एक ही क्षेत्र betwen संबंध (शायद आप क्षेत्र "ग्राहक आईडी" तेह आदेश मेज से ग्राहक तालिका के "आईडी" करने के लिए माउस के साथ घसीटा)

समाधान

तार कि आदेश से कनेक्ट करने और ग्राहक और संबंध में भी जोड़ पर राइट क्लिक करें CompanyId


पीएस: डिज़ाइन सही है।

प्रत्येक तालिका में CompanyId लाना क्योंकि पैमाने पर करने के मदद (आमतौर पर हमेशा loggedIn कंपनी से केवल रिकॉर्ड का चयन करना चाहते) बहु-टेनेंट वास्तुकला में rith समाधान है।

+0

कोई पूर्ण सत्य नहीं है और न ही "बहुसंख्यक के लिए इसका उपयोग करें" में "यौगिक कुंजी का उपयोग न करें" कथन में। डेटाबेस उद्देश्य और उपयोग पर निर्भर करता है। डीडब्ल्यूएच डेटाबेस में मैं यौगिक कुंजी का उपयोग करना चाहता हूं। ओएलटीपी में मैं शायद प्रत्येक तालिका में कंपनी आईडी कॉलम बनाउंगा जो एक गैर-क्लस्टर इंडेक्स वाली रूट इकाई का प्रतिनिधित्व करता है लेकिन यह नहीं देखता कि मुझे इसे कुंजी का हिस्सा क्यों बनाना है ... और गैर रूट इकाइयों में शामिल नहीं किया जा सकता है जैसे ऑर्डर लाइन –

0

यदि आपको प्रत्येक तालिका में पूरी तरह से कंपनी आईडी कॉलम जोड़ना है, तो इसे नियमित कॉलम के रूप में जोड़ें, न कि एक समग्र कुंजी। समग्र कुंजी का उपयोग ज्यादातर तब किया जाता है जब आपको कई रिश्ते में कई लागू करना पड़ता है।

जैसा कि किसी ने उल्लेख किया है कि कंपनी आईडी पर गैर-क्लस्टर इंडेक्स भी बनाते हैं, इसलिए कंपनी टेबल में शामिल हो जाते हैं।

धन्यवाद!

0

पहला: जैसे अन्य लोगों ने कहा, एक विदेशी कुंजी का संदर्भ देते समय, दूसरी तालिका (यानी दोनों फ़ील्ड) में पूरी प्राथमिक कुंजी का उपयोग करें।

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

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

+0

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

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