2010-01-14 16 views
5

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

मेरे पास दो प्रकार हैं जिन्हें मैं हाइबरनेट: समूह और आइटम का उपयोग करना जारी रखना चाहता हूं।
* समूहों को उनके नाम और उनके माता-पिता के संयोजन से विशिष्ट रूप से पहचाना जाता है।
* समूहों को कई पेड़ों में व्यवस्थित किया जाता है, जैसे कि प्रत्येक समूह में शून्य या एक अभिभावक समूह होता है।
* प्रत्येक आइटम शून्य या अधिक समूह का सदस्य हो सकता है।

आदर्श रूप में, मैं एक दो-तरफा संबंध मुझे पाने के लिए अनुमति देता है चाहते हैं:
* सभी समूह है कि एक आइटम
* सभी आइटम है कि एक विशेष समूह या उसके वंश के एक सदस्य हैं का एक सदस्य है।
मुझे यूआई पर प्रदर्शित करने के लिए शीर्ष से समूह के पेड़ को पार करने में भी सक्षम होना चाहिए।

बुनियादी वस्तु संरचना आदर्श रूप इस प्रकार दिखाई देगा:

मूल रूप से, मैं सिर्फ बनाया था एक सरल द्वि-दिशात्मक कई-से-अनेक आइटम और समूह, ऐसी है कि बीच के रिश्ते को एक में सभी आइटम प्राप्त करने में कठिनाई समूह पदानुक्रम आवश्यक प्रत्यावर्तन पेड़, और एक आइटम के लिए समूह लाते एक सरल गेटर, यानी था:

class Group { 
    ... 
    private Set<Item> items; 
    private Set<Group> children; 
    ... 
    /** @return all items in this group and its descendants */ 
    Set<Item> getAllItems() { 
     Set<Item> allItems = new HashSet<Item>(); 
     allItems.addAll(this.items); 
     for(Group child : this.getChildren()) { 
      allItems.addAll(child.getAllItems()); 
     } 
     return allItems; 
    } 

    /** @return all direct children of this group */ 
    Set<Group> getChildren() { 
     return this.children; 
    } 
    ... 
} 

class Item { 
    ... 
    private Set<Group> groups; 
    /** @return all groups that this Item is a direct member of */ 
    Set<Group> getGroups() { 
     return this.groups; 
    } 
    ... 
} 

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

क्या मैं कुछ भी गलत या बेवकूफ कर रहा हूं?


मेरी केवल दूसरे सोचा अब तक यह था: एक अद्वितीय "पथ" स्ट्रिंग जो एक समूह के पूरे वंश को निर्दिष्ट करता है, जैसे के साथ समूह की आईडी, माता-पिता और नाम फ़ील्ड बदलें:
/rootGroup
/rootGroup/aChild
/rootGroup/aChild/aGrandChild

समूह और आइटम के बीच जुड़ने वाली तालिका में समूह_पथ और item_id होगा।

यह तुरंत दो मुद्दों को हल करता है जो मैं पहले पीड़ित था:
1. पूरे समूह पदानुक्रम को एक ही क्वेरी में डेटाबेस से लाया जा सकता है और स्मृति में पुनर्निर्मित किया जा सकता है।
2. एक समूह या उसके वंश में सभी आइटम को पुनः प्राप्त करने के लिए, हम जहां group_path = 'एन' या 'एन /%' की तरह group_path

हालांकि, इस हाइबरनेट का उपयोग कर के बिंदु को हराने के लिए लगता है group_item से चुन सकते हैं। सभी विचारों का स्वागत है!

उत्तर

4

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

दूसरी ओर, पूरे ग्राफ को खींचने से मैनिपुलेशन तेजी से प्रदर्शन करते समय प्रदर्शन सामने आ गया।

दोनों के बीच सबसे बड़ा अंतर आपका विशिष्ट उपयोग केस है। यदि यह एक वेबसर्वर है, तो पूरे ग्राफ को मेमोरी में खींचकर सर्वर को मार देगा। अधिकांश लोग वैसे भी 7-10 विकल्पों को संभाल नहीं सकते हैं, और पूरा ग्राफ यूआई को नेविगेट करने में मुश्किल बनाने वाले विकल्पों के साथ उपयोगकर्ता को आसानी से अभिभूत कर सकता है।

इसके अलावा अनुकूलन के इन नियमों को याद:

  1. गंभीरता से नहीं
  2. करो, मत करो। एक प्रदर्शन समस्या पर हार्डवेयर फेंकना सस्ता है, तो यह उस बिंदु पर आपके कोड को अनुकूलित कर रहा है जो अब और अधिक रखरखाव योग्य नहीं है।
  3. यदि आपको लगता है कि आपको चाहिए, तो एक प्रोफ़ाइल उपकरण का उपयोग करके बाधाएं, और इसे ठीक करें।
+1

Knuth का maxim नहीं है "समयपूर्व अनुकूलन सभी बुराइयों की जड़ है?" –

+0

मुझे लगता है, कई समान मामलों में, यह बड़ी इन-मेमोरी डेटास्ट्रक्चर की समस्या नहीं है बल्कि SQL संचालन की बढ़ती संख्या है। जबकि प्रत्येक परिचालन वास्तव में तेज़ है, जटिल ऑब्जेक्ट-नेट में प्रश्नों की संख्या और संचार की विलंबता को क्रॉल करने के लिए एक आवेदन मिल जाएगा। इस मामले में मैं आमतौर पर नेटवर्क के बड़े हिस्सों की पहचान करना पसंद करता हूं और तकनीकों का उपयोग (पूर्व) उन्हें जितनी जल्दी संभव हो सकता हूं (नीचे अतिरिक्त उत्तर देखें)। मेमोरी आसानी से पुन: उपयोग किया जा सकता है। –

+0

@Mathew हाँ, मुझे विश्वास है कि उसने ऐसा कहा था। @Ralf हम सिर्फ जानकारी नहीं है। मैं बस दोनों अड्डों को कवर करने की कोशिश कर रहा हूँ। –

3

मेरी पिछली परियोजनाओं में मैंने इस समस्या के दो अलग-अलग लेकिन तुलनीय समाधान लागू किए हैं।

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

इस रणनीति का उपयोग करना सभी रूट नोड्स (पेड़ टी से जहां टी.पी.पी.एस. न्यूल) की पहचान करना काफी आसान था और मूल तत्व के आधार पर पूरा पेड़ लाने में वास्तव में आसान था (पेड़ टी से जहां टी.रूट =: जड़)।

रिश्ते "सेट बच्चों" को एक @ ट्रान्सेंट विशेषता घोषित किया गया था। एक साधारण उपयोगिता संचालन का उपयोग करके, किसी भी समय मूल वृक्ष संरचना का पुनर्निर्माण करना काफी आसान था।

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

(level6 संबंधों को उन level1 के रूप में "आलसी कई-टू-वन" रिश्तों मैप किए गए थे और आवेदन 2 स्तर कैश पर भारी dependend था।)

+0

हाय राल्फ, प्रतिक्रिया के लिए धन्यवाद। यह दृष्टिकोण लगता है जैसे यह निश्चित रूप से कुछ मामलों में चीजों को गति देगा, लेकिन मुझे यकीन नहीं है कि यह सभी उपयोग-मामलों पर लागू है या नहीं। – Armand

2

नेस्ट सेट में देखो। यहाँ एक अच्छा लेख है:

http://www.developersdex.com/gurus/articles/112.asp

मूल रूप से, आप कुछ प्रदर्शन बलिदान जब पदानुक्रम आदेश, गहरी retrievals सरल करने के लिए क्या आप वंशज समूहों के सदस्यों के रूप में आइटम के साथ क्या करना चाहते हैं की तरह में संशोधित किया गया है।

+0

बहुत रोचक! मुझे लगता है कि मुझे इसे पूरी तरह से प्राप्त करने से पहले इसे कुछ बार फिर से पढ़ना होगा। – Armand

+0

मदद करने के लिए खुश। जब से मैंने इनके साथ काम किया, तो यह दो साल हो गया है, लेकिन यदि आपके पास विशिष्ट प्रश्न हैं। मेरे द्वारा लिंक किए गए आलेख को दोबारा पढ़ने के बाद, मैंने देखा कि वह कुछ विवरणों पर झुका हुआ है। यहां एक और व्याख्यात्मक लेख है, MySQL की कोर्टी: http://dev.mysql.com/tech-resources/articles/hierarchical-data.html वे आधे रास्ते के बारे में नेस्टेड सेट को कवर करते हैं। – Taylor

1

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