2012-10-15 18 views
17

चलो कहते हैं कि मैं एक grails डोमेन वर्ग लग रहा है किgrails hasOne बनाम प्रत्यक्ष सदस्य चर

तरह
class Person { 
    Address address 
} 

मैं भी

class Person { 
    static hasOne = [address:Address] 
} 

दूसरा तरीका करने के लिए विदेशी कुंजी के लिए कदम होगा के रूप में यह घोषणा कर सकता है चलो व्यक्ति तालिका के बजाय पता तालिका।

इस तरह से एक दूसरे तरीके से करने के व्यावहारिक लाभ (या नुकसान) क्या हैं? जहां तक ​​मैं समझता हूं, वे दोनों विदेशी कुंजी का उपयोग करेंगे, यह सिर्फ एक बात है कि विदेशी कुंजी कहाँ रहती है।

उत्तर

25

यदि पता कुंजी पर विदेशी कुंजी मौजूद है, तो उस पते में केवल एक व्यक्ति हो सकता है। यदि विदेशी कुंजी व्यक्ति तालिका पर है, तो एकाधिक व्यक्तियों का एक ही पता हो सकता है।

यह बेहतर नहीं है कि यह बेहतर/बदतर तरीका है। यह आपके डेटा को मॉडल करने का सही तरीका क्या है।

+0

यह समझ में आता है, धन्यवाद। मुझे यहां से एक मस्तिष्क फार्ट का थोड़ा सा खेद है। मैं grails तंत्र में लपेट गया और डेटाबेस परिप्रेक्ष्य से इसके बारे में सोचने के लिए वापस कदम नहीं उठाया। –

21

मुझे विशेष रूप से भ्रमित होने के लिए Grails में hasOne का उपयोग मिलता है। उदाहरण के लिए, इस सवाल का क्या होता है जब एक Toone संबंध इस प्रकार घोषित किया जाता है पूछते हैं:

class Person { 
    static hasOne = [address: Address] 
} 

जैसा कि ऊपर कहा, इसका मतलब है जो पता तालिका में प्रदर्शित करने के person_id विदेशी कुंजी, का कारण बनता है कि प्रत्येक पता ही बिंदु पर कर सकते हैं एक व्यक्ति। मुझे विचित्र लगता है, फिर भी, यह है कि कोड "एक व्यक्ति के पास एक पता" के रूप में लिखा गया है, वास्तविक परिणाम यह है कि "एक पते में एक व्यक्ति होता है"।

और वास्तव में, केवल ऊपर के रूप में परिभाषित किया गया है, एक ही व्यक्ति पर इंगित करने से एक से अधिक पता रिकॉर्ड को रोकने से कुछ भी नहीं (डेटाबेस स्तर पर) कुछ भी नहीं है, जिसका अर्थ है कि किसी व्यक्ति को वास्तव में एक पता नहीं होना चाहिए ।

दिलचस्प बात यह है कि आप एक ही डेटाबेस प्रतिनिधित्व करता है, तो आप इस तरह पता श्रेणी का निर्माण मिल चाहते हैं:

class Address { 
    Person person 
} 

person_id विदेशी कुंजी सिर्फ पिछले उदाहरण में की तरह के रूप में, पता तालिका में होगा, लेकिन जाहिर है, आप उस संबंध को किसी भी तरीके से परिभाषित किए बिना कोड में पते से पते तक नहीं जा सकते हैं।

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

बेशक, हम केवल डेटाबेस टेबल नहीं बना रहे हैं, हम Grails डोमेन क्लासेस बना रहे हैं जिनके साथ कुछ व्यवहार है, और रिश्ते semantics के कुछ प्रवर्तन। इस विशेष व्यावसायिक उदाहरण में, आप शायद एक ही पता रिकॉर्ड को एकाधिक लोगों के साथ साझा नहीं करना चाहते हैं, आप बस अलग से पता स्टोर करना चाहते हैं (शायद उस दिन की तैयारी कर रहे हैं जब किसी व्यक्ति के पास एकाधिक पते हों)। मैं शायद इस दृष्टिकोण के लिए वोट चाहते हैं:

class Person { 
    Address address 

    static constraints = { 
     address unique:true 
    } 
} 

address_id विदेशी कुंजी व्यक्ति तालिका में हो जाएगा, और अद्वितीय बाधा लागू करेंगे कि कोई भी दो व्यक्ति रिकॉर्ड एक ही पते पर ओर इशारा करते हैं।

+2

वास्तव में दिलचस्प, विचारों के लिए धन्यवाद! –

+0

और 'हैऑन' में प्रदर्शन प्रभाव पड़ता है (कम से कम 2.2.0 में, जिसे मैं फंस गया हूं)। मैं प्रोफाइलिंग कर रहा था और पाया कि एसोसिएशन आलसी लोड हो रहा था, भले ही मैं इसका उपयोग नहीं कर रहा था, जिसके परिणामस्वरूप डीबी को बहुत सारी अनावश्यक यात्राएं हुईं। ऐसा लगता है कि इसे एक सदस्य चर में स्विच करना इसे समाप्त कर देता है। –

7

मैं निम्नलिखित सुझाव है ...

class Person { 
    ... 
    static hasOne = [address: Address] 
} 

class Address { 
    ... 
    static belongsTo = [person: Person] 
} 

एक व्यक्ति को एक पता है और पता किसी एक व्यक्ति के अंतर्गत आता है।

इस तरह, जब आप किसी व्यक्ति को हटाते हैं, तो पता भी बिना किसी समस्या के हटा दिया जाएगा।

मुझे लगता है कि यह करने का यह बेहतर तरीका है।

+0

हालांकि जब आप मर जाते हैं तो घरों को आम तौर पर हटाया नहीं जाता है: डी –

6

व्यक्ति "hasOne" पता और पता "belongsTo" व्यक्ति

"बच्चे" तालिका पर विदेशी कुंजी होने से अधिक समझदारी होती है क्योंकि माता-पिता गुम होने पर बच्चे टूट जाएगा। व्यक्ति इसके पते के बिना मौजूद हो सकता है लेकिन किसी व्यक्ति के बिना "व्यक्ति का पता" कोई समझ नहीं आता है। तो पता संबंधों का कमजोर पक्ष होना चाहिए।

इसे इस तरह से करने के लिए दोनों इकाइयों में एक दूसरे का संदर्भ होगा, इसलिए यह अजीब महसूस नहीं करेगा। इसके अलावा डिफ़ॉल्ट कैस्केडिंग व्यवहार बचाने के लिए और जब आप व्यक्ति बचाने पता को नष्ट करेगा, लेकिन आप पताव्यक्ति सहेजी रहेगी हटाना चाहते हैं।

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