2010-05-21 8 views
6

लिंक के साथ आप कल्पना करते हैं कि आप बहुत सरल उदाहरण भूमि में रहते हैं - और कल्पना करें कि आपके पास लोगों की एक तालिका है अपने MySQL डेटाबेस:लोगों की एक तालिका मिली, जो मैं एक-दूसरे से लिंक करना चाहता हूं, कई-से-कई, बिडरेक्शनल

create table person (
    person_id int, 
    name text 
) 

select * from person; 

+-------------------------------+ 
| person_id |   name | 
+-------------------------------+ 
|   1 |   Alice | 
|   2 |    Bob | 
|   3 |   Carol | 
+-------------------------------+ 

और इन लोगों को सहयोग करने के लिए/एक साथ काम करते हैं, तो आप एक लिंक तालिका जो एक व्यक्ति रिकॉर्ड लिंक मिल गया है की जरूरत है:

create table person__person (
    person__person_id int, 
    person_id int, 
    other_person_id int 
) 

इस सेटअप मतलब यह है कि बीच लिंक लोग यूनी-दिशात्मक हैं - यानी एलिस बॉब से लिंक कर सकता है, बिना बॉब को ऐलिस से जोड़ने और यहां तक ​​कि डब्ल्यू ओर्स, ऐलिस बॉब और से लिंक कर सकता है बॉब एक ​​ही समय में ऐलिस से दो अलग-अलग लिंक रिकॉर्ड में लिंक कर सकता है। चूंकि ये लिंक कामकाजी रिश्तों का प्रतिनिधित्व करते हैं, असली दुनिया में वे सभी दो तरह के पारस्परिक संबंध हैं। इस स्थापना के बाद सब कर रहे हैं संभव:

select * from person__person; 

+---------------------+-----------+--------------------+ 
| person__person_id | person_id | other_person_id | 
+---------------------+-----------+--------------------+ 
|     1 |   1 |     2 | 
|     2 |   2 |     1 | 
|     3 |   2 |     2 | 
|     4 |   3 |     1 | 
+---------------------+-----------+--------------------+ 

उदाहरण के लिए, साथ person__person_id = 4 से ऊपर है, जब आप कैरोल के (person_id = 3) प्रोफ़ाइल देखने पर आपको ऐलिस के साथ एक रिश्ता देखना चाहिए (person_id = 1) और जब आप ऐलिस की प्रोफ़ाइल देखते हैं, आपको कैरल के साथ एक रिश्ता देखना चाहिए, भले ही लिंक दूसरी तरफ जाता है।

मुझे एहसास है कि मैं संघ और विशिष्ट प्रश्न कर सकता हूं और यूआई में पारस्परिक संबंधों को रिश्तों को प्रस्तुत करने के लिए क्या नहीं, लेकिन क्या कोई बेहतर तरीका है? मुझे एहसास हुआ है कि एक बेहतर तरीका है, जहां यह समस्या डेटाबेस को व्यवस्थित करके व्यवस्थित ढंग से पिघल जाएगी, लेकिन मैं इसे नहीं देख सकता। किसी को भी बेहतर विचार मिला?

+3

यह सबसे अच्छा प्रारूपित प्रश्न है जिसे मैंने कभी भी <50 प्रतिनिधि उपयोगकर्ता से देखा है! चीयर्स! –

+1

मैंने 'mysql many-to-many' से 'डेटा-मॉडलिंग कई-से-कई' (+1 अच्छा प्रश्न!) – lexu

+1

+1 से टैग को अच्छी तरह से कहा गया प्रश्न बदल दिया। nit-pick: person__person एक भयानक तालिका का नाम है; बस दावा करें कि यह रोशनी के प्रयोजनों के लिए है;) – msw

उत्तर

3

मैं अपने टेबल कॉन्फ़िगर करने के लिए एक बेहतर तरीका है तो यकीन नहीं है। मुझे लगता है कि आपके पास उनके पास उचित तरीका है और जिस तरह से मैं इसे लागू करूँगा।

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

select * from person__person; 
+---------------------+-----------+--------------------+ 
| person__person_id | person_id | other_person_id | 
+---------------------+-----------+--------------------+ 
|     1 |   1 |     2 | 
|     2 |   2 |     1 | 
+---------------------+-----------+--------------------+ 

कारण है, क्योंकि सिस्टम की तरह ActiveRecord (रेल) का एक बहुत में, कई-से-अनेक तालिका वस्तु नहीं स्मार्ट पर्याप्त होगा: ऐलिस बॉब के साथ सहयोग कर रहा है, तो तालिका इस प्रकार होना चाहिए person_id और other_person_id दोनों से पूछताछ करने के लिए। दो पंक्तियों को रखकर, ऑब्जेक्ट्स जैसे ActiveRecord सही ढंग से काम करेगा।

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

+1

इसमें व्यापार तर्क की योग्यता भी है कि यह निर्णय लेना कि सभी संगठन द्वि-दिशात्मक नहीं हैं, स्कीमा में कोई बदलाव नहीं है। – msw

+0

हो गया और किया गया! बहुत बहुत धन्यवाद - मैं इस विधि के साथ जा रहा हूं, सभी कारणों से उपयोगकर्ता 2390 9 8 और एमएसडब्ल्यू ने कहा। –

2

कोई बेहतर विचार नहीं है। रिलेशनल डेटाबेस जो आप पूछते हैं उसे लागू नहीं कर सकते हैं, इसलिए आपको डेटा पुनर्प्राप्त करने के लिए एक विशेष क्वेरी लिखनी है और बाधा को लागू करने के लिए एक ट्रिगर है।

संबंधित व्यक्तियों @person के लिए मैं के लिए जाना होगा प्राप्त करने के लिए:

SELECT CASE person_id WHEN @person 
      THEN other_person_id 
      ELSE person_id 
     END as related_person_id 
FROM person_person 
WHERE ( [email protected] 
     OR [email protected]) 
+0

जहां खंड में एक 'या' के आसपास हमेशा रखें()। जब आप अधिक संयम जोड़ने से पहले भूल जाते हैं तो बुरी चीजें होती हैं! (उत्तर के लिए +1) – lexu

2

सरल संबंधपरक अवधारणाओं का उपयोग करके मैं कोई रास्ता नहीं देख सकता हूं। आपको अपने व्यक्ति-व्यक्ति संबंधों को लागू करने के लिए "व्यवसाय" कोड जोड़ना होगा।

  • एक तरह से एक डालने ट्रिगर
  • का उपयोग कर एक दूसरे रिश्ते रिकॉर्ड लागू करने के लिए हो सकता है तो "प्राथमिक" (उदाहरण के लिए एक जहाँ person_id अन्य _person_id से छोटा है)
  • तो रिकॉर्ड में से एक घोषित अपने अनुप्रयोगों के लिए दृश्य और गोंद कोड बनाएं (चुनें, अपडेट करें, हटाएं) जो इस ज्ञान के साथ डेटा तक पहुंचते हैं।
2

आप इस पोस्ट उपयोगी पाते हैं चाहिए:

http://discuss.joelonsoftware.com/default.asp?design.4.361252.31

रूप @user पोस्ट आप आम तौर पर बंद द्विदिश रिश्ते प्रति दो रिकॉर्ड बनाने बेहतर हैं (ऐलिस अपने उदाहरण में बॉब और बॉब ऐलिस के लिए)। यह को अधिक पूछताछ करता है और यह संबंधों को सटीक रूप से प्रतिबिंबित करता है। यदि आपके पास सही यूनिडायरेक्शनल रिश्तों हैं, तो यह उड़ने का एकमात्र तरीका है।

+0

धन्यवाद, मैंने उस धागे को पढ़ा; यह मूल रूप से 'इसे दो बार स्टोर करें' समाधान की पुष्टि करता है, जिसके बाद चिल्लाने का भार होता है। मुझे खुशी है कि स्टैक ओवरफ्लो ऐसा नहीं है :) –

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