आमतौर पर, पदानुक्रम में तीन प्रकार के प्रश्न होते हैं जो परेशानी का कारण बनते हैं:
- सभी पूर्वजों को लौटाएं
- सभी वंशजों को लौटाएं
- सभी बच्चों को लौटाएं (तत्काल वंशज)।
यहां एक छोटी सी तालिका है जो MySQL
. में विभिन्न विधियों के प्रदर्शन को दर्शाती है :
Ancestors Descendants Children Maintainability InnoDB
Adjacency list Good Decent Excellent Easy Yes
Nested sets (classic) Poor Excellent Poor/Excellent Very hard Yes
Nested sets (spatial) Excellent Very good Poor/Excellent Very hard No
Materialized path Excellent Very good Poor/Excellent Hard Yes
children
. में , poor/excellent
इसका मतलब है कि उत्तर इस बात पर निर्भर करता है कि क्या आप विधि को आसन्न सूची के साथ मिला रहे हैं, i. इ। parentID
को स्टोर करना प्रत्येक रिकॉर्ड में।
आपके कार्य के लिए, आपको तीनों प्रश्नों की आवश्यकता है:
- पृथ्वी/यूके/डेवोन चीज़ दिखाने वाले सभी पूर्वज
- सभी बच्चे "यूरोप में गंतव्य" (आइटम) दिखाएंगे
- सभी वंशज "यूरोप में गंतव्य" (गणना) दिखाने के लिए
मैं भौतिक पथों के लिए जाऊंगा, क्योंकि इस तरह का पदानुक्रम शायद ही कभी बदलता है (केवल युद्ध, विद्रोह आदि के मामले में)।
path
called नामक एक वर्चर कॉलम बनाएं , इसे अनुक्रमित करें और इसे इस तरह के मान से भरें:
1:234:6345:45454:
जहां संख्याएं उपयुक्त माता-पिता की प्राथमिक कुंजी हैं, सही क्रम में (1
यूरोप के लिए, 234
यूके आदि के लिए)
आपको levels
. नामक तालिका की भी आवश्यकता होगी 1
. से नंबर रखने के लिए करने के लिए 20
(या जो भी अधिकतम नेस्टिंग स्तर आप चाहते हैं)।
सभी पूर्वजों का चयन करने के लिए:
SELECT pa.*
FROM places p
JOIN levels l
ON SUBSTRING_INDEX(p.path, ':', l.level) <> p.path
JOIN places pa
ON pa.path = CONCAT(SUBSTRING_INDEX(p.path, ':', l.level), ':')
WHERE p.id = @id_of_place_in_devon
सभी बच्चों और उनके भीतर के स्थानों की संख्या का चयन करने के लिए:
SELECT pc.*, COUNT(pp.id)
FROM places p
JOIN places pc
ON pc.parentId = p.id
JOIN places pp
ON pp.path BETWEEN pc.path AND CONCAT(pc.path, ':')
AND pp.id NOT IN
(
SELECT parentId
FROM places
)
WHERE p.id = @id_of_europe
GROUP BY
pc.id