क्या हर कोर डेटा रिलेशनशिप में उलटा होना चाहिए?


150

मान लीजिए कि मेरे पास दो एंटिटी कक्षाएं हैं: SocialAppऔरSocialAppType

में SocialApp: मैं एक गुण है appURLऔर एक रिश्ता: type

में SocialAppTypeमैं तीन गुण है: baseURL, nameऔर favicon

SocialAppरिश्ते typeका गंतव्य एक एकल रिकॉर्ड है SocialAppType

एक उदाहरण के रूप में, कई फ़्लिकर खातों के लिए, कई SocialAppरिकॉर्ड होंगे, जिसमें प्रत्येक रिकॉर्ड किसी व्यक्ति के खाते का लिंक होगा। SocialAppType"फ़्लिकर" प्रकार के लिए एक रिकॉर्ड होगा , जो सभी SocialAppरिकॉर्ड इंगित करेगा।

जब मैं इस स्कीमा के साथ एक एप्लिकेशन बनाता हूं, तो मुझे एक चेतावनी मिलती है कि SocialAppTypeऔर दोनों के बीच कोई विपरीत संबंध नहीं है SocialApp

 /Users/username/Developer/objc/TestApp/TestApp.xcdatamodel:SocialApp.type: warning: SocialApp.type -- relationship does not have an inverse

क्या मुझे एक व्युत्क्रम की आवश्यकता है, और क्यों?

जवाबों:


117

व्यवहार में, मुझे उलटा नहीं होने के कारण कोई डेटा हानि नहीं हुई है - कम से कम जो मुझे पता है। एक त्वरित Google बताता है कि आपको उनका उपयोग करना चाहिए:

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

- कोको देव सेंट्रल

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

- कोर डाटा प्रोग्रामिंग गाइड


5
MadNik का उत्तर देखें (इस समय पृष्ठ के निचले भाग में जो मैं यह लिख रहा हूं) डॉक्स के अधिक गहन विवरण के लिए जब वे कहते हैं कि उलटे रिश्ते डेटा अखंडता बनाए रखने में मदद करते हैं।
मार्क ऐमी जूल

135

Apple दस्तावेज़ीकरण का एक शानदार उदाहरण है जो एक ऐसी स्थिति का सुझाव देता है जहां आपको उलटा संबंध नहीं होने से समस्याएं हो सकती हैं। चलो इस मामले में इसे मैप करें।

मान लीजिए कि आपने इसे इस प्रकार प्रस्तुत किया है: यहाँ छवि विवरण दर्ज करें

ध्यान दें कि आप एक है टू-वन "कहा जाता संबंध प्रकार ", से SocialAppकरने के लिए SocialAppType। यह संबंध गैर-वैकल्पिक है और इसमें "अस्वीकृत" नियम है

अब निम्नलिखित पर विचार करें:

SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated

[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];
BOOL saved = [managedObjectContext save:&error];

हम उम्मीद करते हैं कि इस संदर्भ को बचाने में विफल होने के बाद से हमने डिलीट नियम को अस्वीकार कर दिया है क्योंकि संबंध गैर-वैकल्पिक है।

लेकिन यहां जतन सफल हुआ।

कारण यह है कि हमने एक व्युत्क्रम संबंध स्थापित नहीं किया है । उस वजह से, सोशलऐप इंस्टेंस को तब हटा दिया जाता है जब ऐपटाइप हटा दिया जाता है। तो बचत से पहले सोशलऐप के लिए कोई मान्यता नहीं होती है (यह माना जाता है कि कोई सत्यापन नहीं हुआ क्योंकि कोई परिवर्तन नहीं हुआ)। लेकिन वास्तव में एक बदलाव हुआ। लेकिन यह परिलक्षित नहीं होता है।

यदि हम द्वारा appType याद करते हैं

SocialAppType *appType = [socialApp socialAppType];

appType nil है।

अजीब है, है ना? हम एक गैर-वैकल्पिक विशेषता के लिए शून्य प्राप्त करते हैं?

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

SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated

[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];

[socialApp setValue:nil forKey:@"socialAppType"]
BOOL saved = [managedObjectContext save:&error];

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

46

मैं डेव मार्क और जेफ लेमरच द्वारा मोर आईफोन 3 डेवलपमेंट में पाए गए निश्चित उत्तर को याद करूँगा।

Apple आमतौर पर सलाह देता है कि आप हमेशा उलटा बनाएं और निर्दिष्ट करें, भले ही आप अपने ऐप में उलटे संबंध का उपयोग न करें। इस कारण से, यह आपको चेतावनी देता है जब आप एक व्युत्क्रम प्रदान करने में विफल होते हैं।

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

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


24

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


20

कम से कम एक परिदृश्य है जहां एक उलटा बिना कोर डेटा संबंध के लिए एक अच्छा मामला बनाया जा सकता है: जब पहले से ही दो वस्तुओं के बीच एक और मुख्य डेटा संबंध होता है, जो ऑब्जेक्ट ग्राफ को बनाए रखने में सक्षम होगा।

उदाहरण के लिए, एक पुस्तक में कई पृष्ठ होते हैं, जबकि एक पृष्ठ एक पुस्तक में होता है। यह दो-तरफ़ा एक-से-एक रिश्ता है। किसी पृष्ठ को हटाने से केवल संबंध समाप्त होता है, जबकि पुस्तक हटाने से पृष्ठ भी नष्ट हो जाएगा।

हालाँकि, आप प्रत्येक पुस्तक के लिए पढ़े जा रहे वर्तमान पृष्ठ को ट्रैक करना चाह सकते हैं। यह पृष्ठ पर "currentPage" संपत्ति के साथ किया जा सकता है , लेकिन फिर आपको यह सुनिश्चित करने के लिए अन्य तर्क की आवश्यकता है कि पुस्तक में केवल एक पृष्ठ वर्तमान पृष्ठ के रूप में किसी भी समय चिह्नित किया गया है। इसके बजाय, बुक से सिंगल पेज पर करंट पेजेज का संबंध बनाने से यह सुनिश्चित होगा कि हमेशा केवल एक ही मौजूदा पेज होगा, और इसके अलावा, इस पेज को बुक बुक के साथ आसानी से एक्सेस किया जा सकता है।

पुस्तकों और पृष्ठों के बीच मुख्य डेटा संबंध की चित्रमय प्रस्तुति

इस मामले में पारस्परिक संबंध क्या होगा? कुछ हद तक निरर्थक। "myBook" या समान को दूसरी दिशा में वापस जोड़ा जा सकता है, लेकिन इसमें पृष्ठ के लिए "पुस्तक" संबंध में पहले से ही शामिल जानकारी है, और इसलिए यह अपने स्वयं के जोखिम बनाता है। शायद भविष्य में, आप इन संबंधों में से किसी एक का उपयोग कर रहे हैं, जिससे आपके कोर डेटा कॉन्फ़िगरेशन में परिवर्तन होता है। यदि कुछ स्थानों पर page.myBook का उपयोग किया गया है, जहां कोड में page.book का उपयोग किया जाना चाहिए था, तो समस्याएं हो सकती हैं। इससे बचने का एक और तरीका यह भी होगा कि NSManagedObject उपवर्ग में myBook को उजागर न किया जाए जो पृष्ठ तक पहुंचने के लिए उपयोग किया जाता है। हालांकि, यह तर्क दिया जा सकता है कि पहली जगह में उलटा मॉडल नहीं करना सरल है।

उल्लिखित उदाहरण में, वर्तमान संबंध के लिए डिलीट नियम को "नो एक्शन" या "कैस्केड" पर सेट किया जाना चाहिए, क्योंकि "Nullify" के लिए कोई पारस्परिक संबंध नहीं है। (कैस्केड का तात्पर्य है कि आप किताब को पढ़ते हुए हर पृष्ठ को निकाल रहे हैं, लेकिन यह सच हो सकता है यदि आप विशेष रूप से ठंडे हैं और ईंधन की जरूरत है।)

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


धन्यवाद डंकन - यह मेरे पास एक उपयोग के मामले के बेहद करीब है। अनिवार्य रूप से, मुझे किसी पुस्तक का अंतिम पृष्ठ प्राप्त करने में सक्षम होना चाहिए । मुझे इसके लिए एक दृढ़ मूल्य होने की आवश्यकता है ताकि मैं इसे एक विधेय के रूप में उपयोग कर सकूं। मैंने एक "bookIAmLastPageOf" प्रतिलोम स्थापित किया था, लेकिन यह बहुत बकवास है और अन्य समस्याओं का कारण बन रहा है (मुझे ठीक से समझ में नहीं आता है)। क्या आप जानते हैं कि किसी एक मामले के लिए चेतावनी को अक्षम करने का कोई तरीका है?
बेन्जोहॉन

क्या चेतावनी को निष्क्रिय करने का एक तरीका है? मेरे पास अब 2 है: ... एक उलटा होना चाहिए और कोई एक्शन डिलीट नियम नहीं होगा ... हो सकता है कि डिलीट की गई वस्तुओं के लिए रिश्तों में कमी आए । और currentPageके रूप में चिह्नित किया जा सकता है Optional?
स्विफ्टअर्चेक्ट

क्या संबंध के बजाय NSManagedObjectID के रूप में करेंटपेज को स्टोर करना एक मान्य दृष्टिकोण होगा?
user965972

4

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


0

व्युत्क्रम का उपयोग Object Integrityअन्य कारणों के लिए भी किया जाता है (अन्य उत्तर देखें):

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

प्रेषक: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html#//apple_ref/doc-uid/TP40001075-CH17-SW1

प्रदान की गई लिंक आपको विचार देती है कि आपके पास एक inverseसेट क्यों होना चाहिए । इसके बिना, आप डेटा / पूर्णांक खो सकते हैं। इसके अलावा, मौका है कि आप एक वस्तु का उपयोग करते हैं जो nilअधिक संभावना है।


0

आम तौर पर उलटे रिश्ते की कोई जरूरत नहीं है। लेकिन कोर डेटा में कुछ quirks / कीड़े होते हैं जहां आपको एक व्युत्क्रम संबंध की आवश्यकता होती है। ऐसे मामले हैं जहां रिश्ते / वस्तुएं गायब हो जाती हैं, भले ही संदर्भ को बचाने के दौरान कोई त्रुटि न हो, अगर वहाँ उलटे संबंध गायब हैं। इस उदाहरण की जांच करें , जिसे मैंने कोर डेटा के साथ काम करते समय लापता और कैसे वर्कअराउंड प्रदर्शित करने के लिए बनाया था

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.