बहुत बार, पेड़ को एप्लिकेशन आर्किटेक्चर के आधार के रूप में लिया जाता है। एक सरल उदाहरण: देश, देश - क्षेत्र, क्षेत्र - शहर, शहर - संगठन, संगठन - कार्यकर्ता, सामान या कुछ और हैं। एक पेड़ का उपयोग करना काफी तार्किक और उचित है। ऐसी प्रणाली का पदानुक्रम एक निश्चित सार तालिका द्वारा दिखाया गया है। चलो इसे
वस्तु कहते हैं:
CREATE TABLE object ( id NUMBER(11), parent_id NUMBER(11), type VARCHAR2(16) NOT NULL, name VARCHAR2(255) NOT NULL, CONSTRAINT pk_object PRIMARY KEY (id), CONSTRAINT fk_object_parent FOREIGN KEY (parent_id) REFERENCES object (id) ON DELETE CASCADE ENABLE );
इसे कुछ डेटा से भरें:
id | parent_id | type | name ------------------------------------------------------ 1 | NULL | country | 2 | 1 | region | 3 | 1 | region | 4 | 2 | city | 5 | 3 | city |
उसी समय, हम आसानी से उन कनेक्शनों को प्राप्त कर सकते हैं जिनकी हमें एक अनुरोध के साथ आवश्यकता है:
हालाँकि, समस्याएँ तब प्रकट होती हैं जब तालिका में इतने सारे रिकॉर्ड होते हैं कि किसी भी पुनरावर्ती क्वेरी को दो मिनट के लिए निष्पादित किया जाता है, या इससे भी अधिक। पूरी वास्तुकला को बदलने में थोड़ा बहुत देर हो चुकी है ... यहाँ, पेड़ का अपभ्रंश हमारी सहायता के लिए आता है। इस लेख में मैं इस तरह के एक प्रकार के निरूपण के बारे में बात करूंगा।
मुख्य विचार एक भौतिकीकृत प्रतिनिधित्व का उपयोग करना है जो रिश्तों को प्रश्नों के लिए अधिक सुविधाजनक तरीके से संग्रहीत करता है:
CREATE MATERIALIZED VIEW object_fast REFRESH COMPLETE ON DEMAND START WITH trunc(sysdate)+4/24 NEXT (trunc(sysdate)+1)+4/24 AS SELECT rownum id, tree.* FROM ( SELECT CONNECT_BY_ROOT id object_id, CONNECT_BY_ROOT name object_name, CONNECT_BY_ROOT type object_type, id parent_id, name parent_name, type parent_type, level-1 nesting_level FROM object CONNECT BY PRIOR parent_id = id ORDER BY object_id, nesting_level ) tree;; ALTER TABLE object_fast ADD CONSTRAINT pk_object_fast PRIMARY KEY (id);
अब हमारे पास एक भाजित तालिका है जिसे हम अपने प्रश्नों में उपयोग कर सकते हैं।
id | object_id | object_name | object_type | parent_id | parent_name | parent_type | nesting_level ---------------------------------------------------------------------------------------------------------------------- 1 | 1 | | country | 1 | | country | 0 2 | 2 | | region | 2 | | region | 0 3 | 2 | | region | 1 | | country | 1 4 | 3 | | region | 3 | | region | 0 5 | 3 | | region | 1 | | country | 1 6 | 4 | | city | 4 | | city | 0 7 | 4 | | city | 2 | | region | 1 8 | 4 | | city | 1 | | country | 2 9 | 5 | | city | 5 | | city | 0 10 | 5 | | city | 3 | | region | 1 11 | 5 | | city | 1 | | country | 2
जैसा कि आप देख सकते हैं, तालिका में इसके सभी माता-पिता के साथ प्रत्येक ऑब्जेक्ट के कनेक्शन हैं, और nesting_level माता-पिता के स्तर की संख्या है। कृपया ध्यान दें, मैंने आईडी फ़ील्ड को जोड़ा, जो कि आवश्यक नहीं है, लेकिन यदि आप ORM के माध्यम से डेटा तक पहुंचने की योजना बनाते हैं, तो यह काफी उचित है। अब उपरोक्त प्रश्न इस तरह दिखाई देंगे:
ठीक है, और वैकल्पिक रूप से, आप अनुक्रमित जोड़ सकते हैं:
CREATE INDEX object_fast_obj_id ON object_fast (object_id); CREATE INDEX object_fast_par_id ON object_fast (parent_id); CREATE INDEX object_fast_obj_type ON object_fast (object_type); CREATE INDEX object_fast_par_type ON object_fast (parent_type); CREATE INDEX object_fast_nesting ON object_fast (nesting_level);
वह सब है। अपनी ओर से मैं कहूंगा कि हमारी परियोजना पर इस पद्धति ने लगभग 60 बार अनुरोधों की गति में वृद्धि की है। बुद्धिमानी से उपयोग करें और यह मत भूलो कि प्राप्त डेटा हमेशा प्रासंगिक नहीं होगा। मैं इस विधि को केवल शायद ही कभी जोड़ा और हटाए गए ऑब्जेक्ट को लागू करने की सलाह देता हूं। ठीक है, या फिर यह भौतिकीकृत दृश्य के परिचालन अद्यतन को लागू करने के लायक है। कल्पना की उड़ान की कोई सीमा नहीं है ...
अद्यतन: लेख को बदल दिया गया है और
xtender की टिप्पणी के लिए विधि को बहुत सरल बना दिया गया है।