पुनरावर्ती स्वयं जुड़ता है


15

मेरे पास एक commentsटेबल है, जिसे नीचे सरलीकृत किया जा सकता है:

comments
=======
id
user_id
text
parent_id

कहाँ parent_idअशक्त है, लेकिन इसकी मूल टिप्पणी के लिए एक कुंजी हो सकती है।


अब, मैं selectसभी एक विशिष्ट टिप्पणी के वंशज कैसे हो सकते हैं ?
टिप्पणियों के कई स्तर नीचे हो सकते हैं ...

जवाबों:


16

पदानुक्रमित प्रश्न , जैसा कि उन पुनरावर्ती प्रश्नों को जाना जाता है, MySQL के लिए समर्थित नहीं हैं।

हालाँकि वे ओरेकल, माइक्रोसॉफ्ट एसक्यूएल सर्वर, डीबी 2 और पोस्टग्रेक् एसक्यूएल में समर्थित हैं।

यदि आपको वर्कअराउंड की आवश्यकता है, तो आप यहां एक डायनामिक (और इस प्रकार, संभावित रूप से खतरनाक) ट्रिक पा सकते हैं: /programming/8104187/mysql-hierarchical-queries

आप अन्य मॉडल के साथ पदानुक्रमित डेटा को कैसे संग्रहीत करें, इसके बारे में भी चर्चा कर सकते हैं, जैसे कि आसन्न सूची (यानी मूल स्तंभ) के साथ यहां: /programming/192220/what-is-the-most-ffic- सुरुचिपूर्ण तरह से करने के लिए पार्स एक फ्लैट टेबल में एक पेड़ /

सौभाग्य!


मुझे आश्चर्य है कि आपके दूसरे लिंक में यह समाधान खतरनाक कैसे हो सकता है। क्या आप इसे समझा सकते हैं? अन्यथा, साइट पर आपका स्वागत है!
dezso

3
@dezso: क्वेरी के बाद के समय को खुद को छोड़ दें, क्वासोई " * यह अपग्रेड-सेफ नहीं है * क्योंकि MySQL स्पष्ट रूप से सत्र चर व्यवहार को परिभाषित नहीं करता है। हालांकि, यह एक समयबद्ध-क्वेरी में समीपवर्ती सूची से निपटने का एकमात्र तरीका है ।" खतरनाक एक शब्द भी मजबूत हो सकता है ( संभावित रूप से अस्थिर ?), लेकिन मैं सावधानी के पक्ष में गलती करना पसंद करता हूं (इसके अलावा, मैं ओआरएक्स की तुलना में ओरेकल में अधिक जानकार हूं, इसलिए मैं अतिरिक्त सावधानी बरतना चाहता था)। स्वागत के लिए धन्यवाद, वैसे! मैं एसई नेटवर्क के लिए एक लंबे समय तक चलने वाला रहा हूं, और मैंने फैसला किया कि यह थोड़ा वापस भुगतान करने का समय था।
वाल्मोयर

2
[RECURSIVE] सिंटैक्स के साथ अब mysql 8.0 से समर्थित है। dev.mysql.com/doc/refman/8.0/en/with.html
ClearCrescendo

6

यह तालिका डिज़ाइन बिल एंटविन द्वारा वर्णित एसक्यूएल एंटीपैटर्न "नैवे ट्री" है (अपनी एसक्यूएल एंटीपार्ट्स स्ट्राइक बैक प्रस्तुति में स्लाइड 48 से घूरकर )। इस डिजाइन के साथ समस्या विशेष रूप से एक नोड के सभी वंशज (या माता-पिता) प्राप्त करने में कठिनाई है। चूंकि आप MySQL का उपयोग कर रहे हैं, इसलिए आप अन्य RDBMSes में मौजूद सामान्य टेबल एक्सप्रेशन (स्टेटमेंट के साथ और यह RECOSSIVE संशोधक) का उपयोग नहीं कर सकते हैं।

क्या आप के साथ छोड़ दिया है:

  • पदानुक्रमित डेटा संरचना के वैकल्पिक कार्यान्वयन का उपयोग करें ( इस प्रश्न का उत्तर इस पर एक अच्छा संदर्भ हो सकता है)
  • सेल्फ जॉइन क्वेश्चंस का निर्माण एक गहरी सीमा के साथ करें। गहराई = 5 के लिए आप कुछ लाइनों का उपयोग कर सकते हैं:

    SELECT *
    FROM comments AS c1
      JOIN comments AS c2 ON (c2.parent_id = c1.id)
      JOIN comments AS c3 ON (c3.parent_id = c2.id)
      JOIN comments AS c4 ON (c4.parent_id = c3.id)
      JOIN comments AS c5 ON (c5.parent_id = c4.id)
  • RDBMS का उपयोग करें जो RECURSIVE के साथ समर्थन करता है (हालांकि यह सबसे अधिक संभावना अधिकांश लोगों के लिए एक विकल्प नहीं है)


2
मैं यहां बिल कारविन से असहमत हूं। निकटता मॉडल है नहीं एक विरोधी पैटर्न। एक आधुनिक डीबीएमएस के साथ जो पुनरावर्ती प्रश्नों का समर्थन करता है (ओरेकल ने 20 वर्षों से इसका समर्थन किया है) ऐसा मॉडल पुनर्प्राप्त करने और अद्यतन करने के लिए बहुत कुशल है ।
a_horse_with_no_name

5

MySQL पुनरावर्ती प्रश्नों का समर्थन नहीं करता है जैसे कि आपकी आवश्यकता है।

मैंने कुछ समय पहले जो लिखा था वह Stored Procedures था जो ऐसा करने के लिए मॉडल प्रदान करता है।

पहिया को फिर से मजबूत करने के बजाय, मैं आपको इस पर अपने पिछले पोस्ट के लिंक दूंगा:

संक्षेप में, संग्रहीत कार्यविधि मैंने कतार प्रसंस्करण का उपयोग करके प्रीऑर्डर ट्री ट्रैवर्सल किया

  • GetParentIDByID
  • GetAncestry
  • GetFamilyTree

सभी बच्चों के लिए अभिभावक (जैसे गेटफ़ैमिली स्ट्रीर्ड प्रोसीजर)

  • STEP01) parent_idएक कतार से शुरू करें
  • STEP02) parent_idवर्तमान के रूप में अगले को हटाएं
  • STEP03) उन सभी idमूल्यों को सम्‍मिलित करें जिनमें करंट हैparent_id
  • STEP04) टिप्पणी को प्रिंट या इकट्ठा करें
  • STEP05) यदि कतार खाली नहीं है, तो गोटो STEP02
  • STEP06) आप कर रहे हैं !!!

सभी अभिभावकों के लिए बच्चा (गेटएनेट्री स्टोरेज प्रोसीजर की तरह)

  • STEP01) idएक कतार से शुरू करें
  • STEP02) idवर्तमान के रूप में अगले को हटाएं
  • STEP03) करंट का parent_idमान बढ़ाएंid
  • STEP04) टिप्पणी को प्रिंट या इकट्ठा करें
  • STEP05) यदि कतार खाली नहीं है, तो गोटो STEP02
  • STEP06) आप कर रहे हैं !!!

कार्यान्वयन देखने के लिए कृपया मेरी अन्य पोस्ट में संग्रहीत कार्यविधियाँ देखें।

कोशिश करो !!!


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