माइक हिलियर के ब्लॉग में दिखाए गए तरीकों के अलावा पदानुक्रमित डेटा को व्यवस्थित करने के अन्य तरीके भी हैं। मैं एक विधि का उपयोग करना पसंद करता हूं जिसे मैं संक्रमणीय क्लोजर टेबल कहता हूं या संक्षेप में बंद करने की मेज। इस डिज़ाइन में, आप पदानुक्रम के माध्यम से हर पथ को पूर्वज/वंशज जोड़े के रूप में संग्रहीत करते हैं।
create table closure (
ancestor int,
descendant int,
length int,
primary key (ancestor,descendant),
key (descendant,ancestor)
);
insert into closure values
(1,1,0),
(1,3,1),
(1,4,2),
(1,5,3),
(2,2,0),
(3,3,0),
(3,4,1),
(3,5,2),
(4,4,0),
(4,5,1),
(5,5,0);
ध्यान दें कि इस सेट में शून्य लंबाई के "पथ" भी शामिल हैं, यानी एक मेनू आइटम स्वयं का "पैरेंट" है।
अब आप प्रत्येक मेनू आइटम में शामिल हो सकते हैं m
अपने पूर्वजों के प्रत्येक समूह को a
, उन रास्तों से जुड़कर जहां m
वंशज है। वहां से, मेनू आइटम में वापस शामिल हों o
जो पूर्वजों के समूह में है, और आप order
. तक पहुंच सकते हैं ।
order
से "ब्रेडक्रंब्स" की एक स्ट्रिंग बनाने के लिए GROUP_CONCAT() का उपयोग करें पूर्वजों की श्रृंखला में से प्रत्येक, और यह एक स्ट्रिंग बन जाती है जिसे आप अपने इच्छित मेनू क्रम को प्राप्त करने के लिए क्रमबद्ध कर सकते हैं।
SELECT m.*, GROUP_CONCAT(o.`order` ORDER BY a.length DESC) AS breadcrumbs
FROM menu AS m
INNER JOIN closure AS a ON a.descendant = m.id
INNER JOIN menu AS o ON a.ancestor = o.id
GROUP BY m.id
ORDER BY breadcrumbs;
+----+----------+-------+-------------+
| id | name | order | breadcrumbs |
+----+----------+-------+-------------+
| 1 | Father1 | 0 | 0 |
| 3 | Son | 0 | 0,0 |
| 4 | Child | 1 | 0,0,1 |
| 5 | Grandson | 2 | 0,0,1,2 |
| 2 | Father2 | 1 | 1 |
+----+----------+-------+-------------+
ध्यान दें कि ब्रेडक्रंब एक स्ट्रिंग के रूप में क्रमबद्ध होते हैं, इसलिए यदि आपके पास कुछ order
है 2 या 3 अंक वाले अंक, आपको अनियमित परिणाम मिलेंगे। सुनिश्चित करें कि आपका order
सभी संख्याओं में अंकों की संख्या समान होती है।
एक विकल्प के रूप में, आप बस अपने मूल मेनू तालिका में ब्रेडक्रंब स्ट्रिंग्स को स्टोर कर सकते हैं:
ALTER TABLE menu ADD COLUMN breadcrumbs VARCHAR(255);
UPDATE menu SET breadcrumbs = '0,0,1,2' WHERE id = 5;
etc.
फिर आप एक आसान सी क्वेरी कर सकते हैं:
SELECT * FROM menu ORDER BY breadcrumbs;
लेकिन फिर यह आप पर निर्भर करता है कि आप सभी प्रभावित ब्रेडक्रंब स्ट्रिंग्स की मैन्युअल रूप से पुनर्गणना करें, यदि आप कभी भी मेनू आइटम का क्रम बदलते हैं।