SQL INDEX - यह कैसे काम करता है?


19

डेटाबेस और एसक्यूएल के बारे में मेरा ज्ञान विश्वविद्यालय की अधिकांश कक्षाओं पर आधारित है। किसी भी तरह, मैंने एक कंपनी में कुछ मठ (लगभग एक वर्ष) बिताए, जहां मैं डेटाबेस के साथ काम कर रहा था।

मैं कुछ किताबें पढ़ लिया है और मैं इस तरह के रूप डेटाबेस के बारे में कुछ प्रशिक्षण में भाग लिया है MySQL, PostgreSQL, SQLite, Oracleऔर भी कुछ nonSQL dbजैसे हमें MongoDB, Redis, ElasticSearchआदि

साथ ही मैंने कहा, मैं ज्ञान की कमी के साथ भीख माँगता हूँ, लेकिन आज, किसी ने कुछ बताया, जो मेरे भिखारी के ज्ञान के खिलाफ है।

मुझे समझाने दो। चलो SQL डेटाबेस लेते हैं और Personअंदर कुछ रिकॉर्ड के साथ सरल तालिका बनाते हैं :

id | name   | age
-----------------
1  | Alex   | 24
2  | Brad   | 34
3  | Chris  | 29
4  | David  | 28
5  | Eric   | 18
6  | Fred   | 42
7  | Greg   | 65
8  | Hubert | 53
9  | Irvin  | 17
10 | John   | 19
11 | Karl   | 23

अब, यह हिस्सा है, मैं इस पर ध्यान केंद्रित करना चाहूंगा - idहै INDEX

अब तक, मैंने सोचा था कि यह इस तरह से काम करता है: जब एक तालिका बनाई जा रही INDEXहै तो खाली है। जब मैं अपनी तालिका में नया रिकॉर्ड जोड़ रहा हूं तो INDEXकुछ alghortims के आधार पर पुनर्गणना की जा रही है। उदाहरण के लिए:

एक के बाद एक समूह बनाना:

1    ... N
N+1  ... 2N
     ...
XN+1 ... (X+1)N

इसलिए, मेरे उदाहरण के लिए size = 11 elementsऔर N = 3यह इस तरह होगा:

id | name   | age
-----------------
1  | Alex   | 24     // group0
2  | Brad   | 34     // group0
3  | Chris  | 29     // group0
4  | David  | 28     // group1
5  | Eric   | 18     // group1
6  | Fred   | 42     // group1
7  | Greg   | 65     // group2
8  | Hubert | 53     // group2
9  | Irvin  | 17     // group2
10 | John   | 19     // group3
11 | Karl   | 23     // group3

इसलिए, जब मैं क्वेरी का उपयोग कर रहा हूं तो SELECT * FROM Person WHERE id = 8यह कुछ सरल गणना करेगा 8 / 3 = 2, इसलिए हमें इस ऑब्जेक्ट को देखना group2होगा और फिर यह पंक्ति वापस आ जाएगी:

8  | Hubert | 53

यहां छवि विवरण दर्ज करें

यह दृष्टिकोण उस समय में काम करता है O(k)जहां k << size। बेशक, समूहों में पंक्तियों को व्यवस्थित करने के लिए एक अलगता निश्चित रूप से अधिक जटिल है, लेकिन मुझे लगता है कि यह सरल उदाहरण मेरी बात को दर्शाता है।

इसलिए अब, मैं एक और दृष्टिकोण प्रस्तुत करना चाहूंगा, जो आज मुझे दिखाया गया है।

आइए एक बार फिर से इस तालिका को लें:

id | name   | age
-----------------
1  | Alex   | 24
2  | Brad   | 34
3  | Chris  | 29
4  | David  | 28
5  | Eric   | 18
6  | Fred   | 42
7  | Greg   | 65
8  | Hubert | 53
9  | Irvin  | 17
10 | John   | 19
11 | Karl   | 23

अब, हम Hashmap(वास्तव में, यह हैश मैप है) के समान कुछ बना रहे हैं , जो इस आईडी के साथ पंक्ति में मैप idकरता addressहै। हम कहते हैं:

id | addr 
---------
1  | @0001
2  | @0010
3  | @0011
4  | @0100
5  | @0101
6  | @0110
7  | @0111
8  | @1000
9  | @1001
10 | @1010
11 | @1011

इसलिए अब, जब मैं अपनी क्वेरी चला रहा हूं: SELECT * FROM Person WHERE id = 8

यह सीधे id = 8मेमोरी में पता करने के लिए मैप करेगा और पंक्ति वापस आ जाएगी। बेशक इसकी जटिलता है O(1)

इसलिए अब, मुझे कुछ प्रश्न मिले हैं।

1. दोनों समाधानों के रोमांच और अव्यवस्थाएं क्या हैं?

2. वर्तमान डेटाबेस कार्यान्वयन में कौन अधिक लोकप्रिय है? शायद अलग-अलग डीबीएस अलग-अलग तरीकों का उपयोग करते हैं?

3. क्या यह nonSQL dbs में मौजूद है?

पहले ही, आपका बहुत धन्यवाद


तुलना

               |      B-tree     |   Hash Table
----------------------------------------------------
----------------   one element   -------------------
----------------------------------------------------
SEARCHING      |  O(log(N))      | O(1) -> O(N)  
DELETING       |  O(log(N))      | O(1) -> O(N)
INSERTING      |  O(log(N))      | O(1) -> O(N)
SPACE          |  O(N)           | O(N)
----------------------------------------------------
----------------    k elements   -------------------
----------------------------------------------------
SEARCHING      |  k + O(log(N))  | k * O(1) -> k * O(N)
DELETING       |  k + O(log(N))  | k * O(1) -> k * O(N)
INSERTING      |  k + O(log(N))  | k * O(1) -> k * O(N)
SPACE          |  O(N)           | O(N)

एन - रिकॉर्ड की संख्या

क्या मैं सही हू? प्रत्येक डालने / हटाने के बाद बी-ट्री और हैश टेबल के पुनर्निर्माण की लागत के बारे में क्या ? बी-ट्री के मामले में हमें कुछ संकेत बदलने होंगे लेकिन संतुलित बी-ट्री के मामले में इसे और अधिक प्रयास की आवश्यकता है। साथ ही हैश टेबल के मामले में हमें कुछ ऑपरेशन करने होंगे, खासकर, अगर हमारे ऑपरेशन में टकराव उत्पन्न होता है


2
दूसरे तरीके में, आप एक हैश इंडेक्स का वर्णन कर रहे हैं। आपके बारे में O(1)यह सही है! पहले तरीके से, ऐसा लगता है कि आप बी-ट्री इंडेक्स का वर्णन कर रहे हैं लेकिन आपको कुछ गलतफहमी है। कोई गणना नहीं है (3 या कुछ भी विभाजन), यह अधिक जटिल है क्योंकि पेड़ में अधिक स्तर हैं (यह एक पेड़ है, इसकी बड़ी, छोटी, छोटी शाखाएं हैं ..., और फिर छोड़ देता है :)
ypercubeᵀᴹ

3
BTrees: en.m.wikipedia.org/wiki/B-tree आश्चर्य है कि आपके विश्वविद्यालय में ऐसा कोई एल्गोरिदम पाठ्यक्रम नहीं था जिसने यह समझाया
फिलो

@ypercube हाय, आपके उत्तर के लिए धन्यवाद। साथ ही मैंने लिखा है: Of course, an alghoritm to organise rows in groups is for sure much more complicated but I think this simple example shows my point of view.बेशक, मुझे पता है कि यह बहुत अधिक जटिल है। तो आखिरकार, जब मैं अपने कोड में कह रहा हूं कि मेरा INDEXकौन सा समाधान ( पहला या दूसरा ) इस वास्तविक के करीब है? और समय के आधार पर रिकॉर्ड तक पहुंचने के लिए क्या आवश्यक था INDEX। क्या यह वास्तव में है O(1)? बी-ट्री इंडेक्स के साथ यह बहुत अच्छा लगता है O(log2(N))। क्या मैं सही हू?
रुहुंग्री

@FreshPhilOfSO मुझे लगता है (और भी, मुझे यकीन है) यह उस बारे में कुछ व्याख्यान थे। शायद, मुझे कुछ याद आया ...
ruhungry

ElasticSearch उल्टे अनुक्रमित, पूरी तरह से बी पेड़ से अलग का उपयोग करता elastic.co/blog/found-elasticsearch-from-the-bottom-up
Lluis मार्टिनेज

जवाबों:


12

आप मूल रूप से बी-ट्री इंडेक्स और हैश इंडेक्स का वर्णन कर रहे हैं। उन दोनों के पास एक जगह है, लेकिन दोनों अलग-अलग नौकरियों के लिए सबसे उपयुक्त हैं।

फायदे और नुकसान

बी-ट्री (और बी + -ट्री) सूचकांक आमतौर पर संतुलित होते हैं। इसका मतलब है कि मूल्य की तलाश में हमेशा वही समय लगेगा जहाँ कोई भी पेड़ गिरता है (O (log n))। आम तौर पर, पेड़ में स्तरों की संख्या सीमित होती है, इसलिए यह "व्यापक" हो जाता है "गहरा" नहीं। छोटे डेटा सेटों के लिए, बी-ट्री को बनाए रखने और उपयोग करने की लागत, हालांकि, सभी पंक्तियों को पढ़ने से अधिक हो सकती है। बी-ट्री इंडेक्स बड़े डेटा सेट, कम चयनात्मकता के साथ डेटा सेट या डेटा सेट के लिए अच्छे होते हैं, जहाँ आप वस्तुओं की एक श्रृंखला का चयन करना चाहते हैं, न कि केवल एक वस्तु।

हैश टेबल छोटे डेटा सेट के लिए बढ़िया हैं। हैश इंडेक्स में हैश बाल्टी का पूर्वनिर्धारित नंबर होता है, जिसका उपयोग हैशिंग एल्गोरिथम पर निर्भर करता है। ऐसा इसलिए है क्योंकि एक दिया गया हैश एल्गोरिथ्म केवल इतने ही अनोखे हैश का उत्पादन कर सकता है, इसलिए यह केवल "गहरा" हो जाता है "व्यापक" नहीं। एक बार जब डेटाबेस इंजन सही बाल्टी पाता है, तो यह उस बाल्टी में सभी वस्तुओं के माध्यम से चलता है जिसे आप चाहते हैं। छोटे, उच्च चयनात्मक डेटा सेट के साथ प्रत्येक बाल्टी में बहुत कम संख्या में ऑब्जेक्ट होते हैं और इसे बहुत जल्दी हल किया जाता है। बड़े डेटा सेट के साथ, बाल्टियों में अधिक भीड़ होती है। इसलिए, यदि आपको आवश्यक वस्तु एक छोटी बाल्टी में है या बाल्टी की शुरुआत के पास है, तो यह बहुत जल्दी लौटता है। यदि यह एक बड़ी बाल्टी के अंत में है, तो अधिक समय लगता है। सूचकांक संतुलित नहीं है, इसलिए प्रदर्शन ओ (1) से ओ (एन) तक कहीं भी है।

लोकप्रियता

सामान्य तौर पर, मैंने बी-पेड़ों को सबसे अधिक चलाया है। बिटमैप इंडेक्स कम कार्डिनलिटी के साथ मूल्यों के लिए एक अन्य विकल्प भी है (सोच बूलियन या शायद लिंग)। यह आपके डेटाबेस इंजन पर निर्भर करता है कि सूचकांक प्रकार क्या उपलब्ध हैं।

NoSQL

NoSQL डेटाबेस निश्चित रूप से इंडेक्स का समर्थन करते हैं। अधिकांश बी-ट्री का समर्थन करते हैं या बी-ट्री पर भिन्नता है। अधिकांश हैशेड इंडेक्स का भी समर्थन करते हैं।


4
मुझे नहीं लगता कि बी + पेड़ों में स्तरों की संख्या तय है। जहाँ तक मुझे पता है कम से कम SQL-Server में नहीं।
ypercube y

1
यह सच है। एक बी-ट्री में किसी भी स्तर का स्तर हो सकता है, लेकिन यह आम तौर पर 3 या 4 तक सीमित है। मैंने अपना जवाब संपादित किया।
सरमे

हाय @ सरमे। मुझे वास्तव में आपका उत्तर पसंद है। यह बहुत कुछ समझाता है। अगर आपको इस सवाल का जवाब देना शुरू करना है तो आप बुरा न मानें? शायद कोई व्यक्ति कुछ दिलचस्प जोड़ देगा।
रुहुंग्री

1
क्या आपके पास बिटमैप इंडेक्स के लिए कम कार्डिनैलिटी का मतलब नहीं है?
Mihai

1
सही, कम कार्डिनैलिटी। मुझे बिस्तर के समय से ठीक पहले सवालों का जवाब देना बंद करना होगा :)। उत्तर अपडेट किया गया।
सरमे

4

दोनों समाधानों के रोमांच और अव्यवस्थाएं क्या हैं? दूसरा समाधान रेंज स्कैन नहीं कर सकता है। यह एकल आईडी का चयन करने के लिए बहुत अच्छा है। लेकिन क्या होगा यदि आप आईडी 3 को 8 के माध्यम से चाहते हैं? इसे सभी रिकॉर्डों को व्यक्तिगत रूप से हड़पना होगा जो वास्तविक दुनिया में सिर्फ O (1) * 6 रिकॉर्ड प्राप्त करने के लिए नहीं है। HashMap सूचकांक के साथ एक बड़े, उत्पादन डेटाबेस में आपको विभिन्न पृष्ठों पर रिकॉर्ड मिलेगा, आपको डिस्क को हिट करने और स्मृति में छह अलग-अलग पृष्ठों को पढ़ने की आवश्यकता होती है।

बी-ट्री संरचना में, जैसे कि आपकी पहली स्थिति वास्तव में कैसे लागू की जाएगी, आईडी डिस्क पर अनुक्रमिक होगी और एक एकल पृष्ठ की संभावना आईडी 3 - 8 होगी जो रेंज स्कैन की गति को बढ़ाकर व्यक्तिगत पहुंच ओ (लॉग एन) बना देगा। ।

वर्तमान डेटाबेस कार्यान्वयन में कौन सा अधिक लोकप्रिय है? शायद अलग-अलग डीबीएस अलग-अलग तरीकों का उपयोग करते हैं? मेरे पास विभिन्न डेटाबेस में बहुत बड़ा अनुभव नहीं है। मुझे पता है कि Sql Server ज्यादातर B-Trees का उपयोग करता है, लेकिन SQl 2014 में कुछ नए हैश इंडेक्स हैं जिनका उपयोग आप निश्चित टेबल पर कर सकते हैं। मैंने बहुत सारे एसक्यूएल डेटाबेस और कैशिंग डेटाबेसों को अलग-अलग रिकॉर्ड्स को प्राप्त करने के लिए बनाया हैश के साथ-साथ हैश इंडेक्स का भी उपयोग करते हुए सुना है। यह कैश के लिए समझ में आता है क्योंकि आप उपयोगकर्ता ए पेज 11 के लिए रिकॉर्ड चाहते हैं और रेंज स्कैन की आवश्यकता नहीं है।

क्या यह nonSQL dbs में मौजूद है? हाँ। Postgressql के लिए बनाएं इंडेक्स डॉक्यूमेंटेशन पर एक त्वरित नज़र डालें तो मुझे लगता है कि यह हैश और बी-ट्री इंडेक्स दोनों के साथ-साथ कुछ अन्य का भी समर्थन करता है।

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