2010-03-15 15 views
7

मैं ऐसी सुविधा बनाने की सोच रहा हूं जो पदानुक्रमित फ़िल्टरिंग वाले डेटा के लिए पूछताछ की अनुमति देता है। मेरे पास कुछ विचार हैं कि मैं इसके बारे में कैसे जा रहा हूं लेकिन यह सोच रहा था कि क्या कोई सिफारिशें या सुझाव हैं जो अधिक कुशल हो सकते हैं।पदानुक्रमित डेटा खोजने के लिए सर्वोत्तम विधि

उदाहरण के तौर पर एक उपयोगकर्ता कल्पना करता है कि कोई उपयोगकर्ता नौकरी की तलाश में है। नौकरी के क्षेत्र निम्नानुसार होंगे।

1: Scotland 
2: --- West Central 
3: ------ Glasgow 
4: ------ Etc 
5: --- North East 
6: ------ Ayrshire 
7: ------ Etc 

एक उपयोगकर्ता विशिष्ट (अर्थात ग्लासगो) या एक बड़े क्षेत्र (अर्थात स्कॉटलैंड) में खोज सकते हैं।

दो दृष्टिकोण मैं विचार कर रहा हूँ कर रहे हैं:

  1. प्रत्येक रिकॉर्ड के लिए डेटाबेस में बच्चों का एक नोट रखने के (यानी बिल्ली 1 होता 2, 3, अपने बच्चों के क्षेत्र में 4) और है कि रिकॉर्ड के खिलाफ क्वेरी SELECT * FROM Jobs WHERE Category IN Areas.childrenField के साथ।
  2. चयनित क्षेत्र से संबंधित सभी परिणामों को खोजने के लिए एक पुनरावर्ती फ़ंक्शन का उपयोग करें।

समस्याओं मैं दोनों कर रहे हैं से देखें:

  1. DB में इस डेटा होल्डिंग संरचना करने के लिए सभी परिवर्तनों का ट्रैक रखने के लिए होने का मतलब होगा।
  2. रिकर्सन धीमा और अक्षम है।

सर्वोत्तम दृष्टिकोण पर कोई विचार, सुझाव या सिफारिशें? मैं एमएसएसक्यूएल 2005 डीबी के साथ सी # एएसपी.नेट का उपयोग कर रहा हूं।

+0

आप क्या कर सकते हैं पुनरावर्ती प्रश्नों, अपनी तालिका संरचना यह समर्थन करता है तो: http: // msdn.microsoft.com/en-us/library/ms186243.aspx – FrustratedWithFormsDesigner

+0

क्या आपने XML में अपनी जानकारी मॉडलिंग करने और इसे XML विशेषता (डेटाबेस तालिका पर) में संग्रहीत करने पर विचार किया है ताकि आप XQuery का उपयोग करके क्वेरी कर सकें? – XpiritO

उत्तर

2

यहाँ एक दृष्टिकोण मैं इस्तेमाल किया देखा है। सभी रूट ऑब्जेक्ट्स के लिए आधार आईडी उत्पन्न करें। प्रत्येक बच्चे ऑब्जेक्ट के लिए एक आईडी उत्पन्न करता है और इसे माता-पिता (ओं) आईडी के साथ प्रीपेड करता है।

उदाहरण तालिका

ID(PK) HierarchyID Area 
1  sl   Scotland 
2  slwc  West Central 
3  slwcgg  Glasgow 

उदाहरण क्वेरी

SELECT * FROM Areas Where HierarchyID LIKE 'sl%' 
+0

दिलचस्प तकनीक! – FrustratedWithFormsDesigner

+2

SQL सर्वर 2008 में, उन्होंने इस दृष्टिकोण को संभालने के लिए डेटा प्रकार, पदानुक्रमित किया है: http://msdn.microsoft.com/en-us/magazine/cc794278.aspx –

+0

यह दृष्टिकोण थोड़ा अलग कार्यान्वयन की तरह दिखता है मेरा विकल्प 1 विचार। अच्छा और सरल, हालांकि इसका मतलब यह होगा कि हर बार श्रेणी में अपडेट होने पर हीराचैडआईड को फिर से पेश करने की आवश्यकता होगी। – WDuffy

1

आपको नेस्टेड सेट का उपयोग करना चाहिए। MySQL में एक कार्यान्वयन यहां दिया गया है। http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

+0

वह MSSQL का उपयोग कर रहा है, MySQL नहीं। – FrustratedWithFormsDesigner

+0

यह उत्तर पदानुक्रमित डेटा से निपटने के लिए एक तकनीक के रूप में "नेस्टेड सेट" के बारे में है। वह सिर्फ एक अच्छी व्याख्या से जुड़ा हुआ है जो एक MySQL साइट पर होता है। इसमें कुछ भी शामिल नहीं है जो MySQL- विशिष्ट है। – patmortech

2

आप रिकर्सिव क्वेरी करने के लिए Common Table Expressions का उपयोग कर सकते हैं। मुझे यह तकनीक बहुत शक्तिशाली, पढ़ने में आसान और बनाए रखने में आसान लगता है।

hierarchyid नामक एक varchar (max) क्षेत्र बनाएं:

1

कैसे इस बारे में?

टेबल =>

ईद ParentId नाम

अच्छा सरल तालिका?

फिर कुछ अच्छे जटिल टुकड़े पीएफ एसक्यूएल के साथ जाने के बारे में कैसे? (सीटीई रॉक मुझे लगता है कि)

public object FetchCategoryTree() 
{ 
    var sql = @"SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 

    WITH AreaTree (ID, Name, ParentID, OrgLevel, SortKey) AS 
    (
     -- Create the anchor query. This establishes the starting 
     -- point 
     SELECT 
      a.ID, 
      cast('---- ' + a.Name as varchar(255)), 
      a.ParentID, 
      cast('----' as varchar(55)), 
      CAST(a.ID AS VARBINARY(900)) 
     FROM dbo.Area a 
     WHERE a.ParentID is null 
     UNION ALL 
     -- Create the recursive query. This query will be executed 
     -- until it returns no more rows 
     SELECT 
      a.ID, 
      cast('----' + b.OrgLevel + ' ' + a.Name as varchar(255)), 
      a.ParentID, 
      cast(b.OrgLevel+ '----' as varchar(55)), 
      CAST(b.SortKey + CAST (a.ID AS BINARY(4)) AS VARBINARY(900)) 
     FROM dbo.Area a 
       INNER JOIN AreaTree b ON a.ParentID = b.ID 
    ) 
    SELECT * FROM AreaTree 
    ORDER BY SortKey"; 

    return FetchObject(sql); 
} 

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

आपको एक प्रकार की कुंजी संलग्न के साथ पंक्तियों का एक समूह मिल जाएगा। एक बार जब आप सॉर्ट कुंजी से क्वेरी ऑर्डर करेंगे तो आपको जवाब मिलेगा:

---- parent 1 
-------- child 1 
-------- child 2 
------------ child 2.1 
---- parent 2 
-------- etc 

क्या आप देख रहे हैं?

0

मैं अपने आवेदन में बिक्री कर पदानुक्रम (राज्य/काउंटी/शहर/Misc) के लिए जो सेल्को के पेड़ मॉडल का उपयोग करता हूं और यह अच्छी तरह से काम करता है।

आपकी क्वेरी "इस क्षेत्र में या नीचे नौकरी खोजने" कुछ इस तरह दिखेगा:

SELECT * FROM Jobs WHERE Jobs.AreaID IN 
(SELECT P1.AreaID 
FROM Areas AS P1, Areas AS P2 
WHERE P1.lft BETWEEN P2.lft AND P2.rgt 
AND P2.Areas.AreaID = @selectedAreaID) 

Celko Tree in SQL article

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