Tere, Habr! Esitlen teile tÔlget artiklist
.
Kui jutt kĂ€ib relatsioonilistest andmebaasidest, ei saa ma jĂ€tta mĂ”tlemata, et midagi on puudu. Need on igal pool. On mitmeid erinevaid andmebaase: alates vĂ€ikesest ja kasulikust SQLite'ist kuni vĂ”imsa Teradata'ni. Kuid ainult mĂ”ned artiklid selgitavad, kuidas andmebaas töötab. Sa saad ise otsida fraasiga "howdoesarelationaldatabasework" («kuidas töötavad relatsioonilised andmebaasid»), et nĂ€ha, kui vĂ€he tulemusi on. Veelgi enam, need artiklid on lĂŒhikesed. Kui aga otsid viimaseid pĂ”nevaid tehnoloogiaid (Big Data, NoSQL vĂ”i JavaScript), leiad sĂŒgavamate selgitustega artikleid.
Kas relatsioonilised andmebaasid on liiga vanad ja igavad, et neist vĂ€ljaspool ĂŒlikooli kursusi, teadusuuringute töid ja raamatuid rÀÀkida?

Arendajana vihkan ma kasutada midagi, mida ma ei mĂ”ista. Ja kui andmebaasid on olnud kasutusel ĂŒle 40 aasta, peab sellel olema pĂ”hjus. Nende aastate jooksul olen kulutanud sadu tunde, et tĂ”eliselt mĂ”ista neid kummalisi musti kaste, mida kasutan iga pĂ€ev. Suhtelised andmebaasid on vĂ€ga huvitavad, kuna need tuginevad kasulikele ja korduvalt kasutatavatele kontseptsioonidele.Kui sind huvitab andmebaasi mĂ”istmine, kuid sul pole kunagi olnud aega vĂ”i soovi seda laia teemat uurida, peaks see artikkel sulle meeldima.
Kuigi selle artikli pealkiri on selge, ei ole selle artikli eesmĂ€rk mĂ”ista, kuidas andmebaasi kasutada.SeetĂ”ttu pead sa juba teadma, kuidas kirjutada lihtsat ĂŒhenduspĂ€ringut ja pĂ”hikĂŒsimusi; CRUDvastasel juhul vĂ”id sa seda artiklit mitte mĂ”ista. See on ainus, mida pead teadma; ma selgitan kĂ”ike muud.
Alustan mĂ”ningatest arvutitarkuse pĂ”hialustest, nagu algoritmide ajakompleksus (Big O). Ma tean, et mĂ”ned teist vihkavad seda kontseptsiooni, kuid ilma selleta ei saa sa mĂ”ista andmebaasi sisemisi nĂŒansse. Kuna see on tohutu teema, keskendun sellele, mida pean oluliseks,: kuidas andmebaas töötab. SQL taotlusKodan ainult pĂ”hialuste kontseptsioonid andmebaasi,et artikli lĂ”puks oleks sul arusaam, mis toimub kapoti all.
Kuna see on pika ja tehnilise artikli, mis sisaldab paljusid algoritme ja andmestruktuure, Ă€rge kiirustage selle lugemisega. MĂ”ned kontseptsioonid vĂ”ivad olla keerulised mĂ”ista; vĂ”ite need vahele jĂ€tta ja ikkagi saada ĂŒldise ĂŒlevaate.
Teie teadlikumate jaoks on see artikkel jagatud kolmeks osaks:
- Andmebaasi madala ja kĂ”rge taseme komponentide ĂŒlevaade
- KĂŒsimuste optimeerimise protsessi ĂŒlevaade
- Tehingute ja puhverpanga haldamise ĂŒlevaade
Tagasi pÔhialuste juurde
Palju aastaid tagasi (kauges, kauges galaktikasâŠ) pidid arendajad tĂ€pselt teadma, kui palju toiminguid nad kodeerivad. Nad teadsid oma algoritme ja andmestruktuure peast, kuna nad ei saanud endale lubada oma aeglaste arvutite CPU ja mĂ€lu raiskamist.
Selles osas meenutan teile mÔningaid neist kontseptsioonidest, kuna need on vajalikud andmebaasi mÔistmiseks. Tutvustan ka mÔistet andmebaasi indeks.
O(1) vs O(n2)
Praegu ei hooli paljud arendajad algoritmide ajaloogilisest keerukusest⊠ja nad on Ôiged!
Kuid kui tegelete suure andmemahuga (ma ei rÀÀgi tuhandetest) vĂ”i kui vĂ”itlete millisekundite eest, on ĂŒlioluline mĂ”ista seda kontseptsiooni. Nagu te teate, peavad andmebaasid tegelema mĂ”lema olukorraga! Ma ei lase teil kulutada rohkem aega, kui on vajalik, et haarata olemus. See aitab meil hiljem mĂ”ista kulupĂ”hise optimeerimise kontseptsiooni (cost based optimization).
Kontseptsioon
Algoritmi ajaloogiline keerukus kasutatakse, et nÀha, kui kaua peab algoritm andmemahu töötlemiseks aega vÔtma.Selle keerukuse kirjeldamiseks kasutatakse suurte O matemaatilisi tÀhistusi. Seda mÀrkust kasutatakse funktsiooniga, mis kirjeldab, kui palju toiminguid on algoritmil antud sisendandmete hulga jaoks vaja.
NĂ€iteks kui ma ĂŒtlen, "see algoritm on keerukusega O (some_function() )", tĂ€hendab see, et teatud andmehulgaga töötlemiseks on algoritm vajanud some_function(a_certain_amount_of_data) toimingut.
Selle juures tÀhtis ei ole andmete hulk**, vaid see, ** kuidas toimingute arv kasvab andmemahu suurenedes.Ajakeerukus ei anna tÀpset toimingute arvu, vaid on hea viis ajakulu hindamiseks.

Sellel diagrammil nĂ€ete seost operatsioonide arvu ja sisendandmete mahtu erinevate ajakulu keerukuse tĂŒĂŒpide vahel. Kasutasin logaritmilist skaala nende kuvamiseks. TeisisĂ”nu, andmete hulk kasvab kiiresti 1-st kuni 1 miljardi. Saame nĂ€ha, et:
- O(1) vÔi konstantne keerukus jÀÀb pidevaks (vastasel juhul ei saaks seda nimetada konstantseks keerukuseks).
- O(log(n)) jÀÀb madalaks isegi miljardite andmetega.
- Halvim keerukus on O(n2), kus operatsioonide arv kasvab kiiresti.
- Kaks muud keerukust kasvavad samuti kiiresti.
NĂ€ited
VÀikese andmemahu korral on erinevus O(1) ja O(n2) vahel ebaoluline. NÀiteks oletame, et teil on algoritm, mis peab töötlema 2000 elementi.
- O (1) algoritm maksab teile 1 operatsiooni
- O (log (n)) algoritm maksab teile 7 operatsiooni
- O (n) algoritm maksab teile 2000 operatsiooni
- O (n * log (n)) algoritm maksab teile 14 000 operatsiooni
- O (n2) algoritm maksab teile 4 000 000 operatsiooni
O(1) ja O(n2) vahe tundub suur (4 miljonit operatsiooni), kuid te kaotate maksimaalselt 2 ms, lihtsalt silmapilgutamise aja. TÔepoolest, tÀnapÀevased protsessorid suudavad töödelda . SeetÔttu ei ole paljude IT-projektide puhul jÔudlus ja optimeerimine probleem.
Nagu juba mainitud, on selle kontseptsiooni tundmine endiselt oluline, kui töötate tohutu andmemahuga. Kui seekord peab algoritm töötlema 1 000 000 elementi (mis ei ole eriti palju andmebaasi jaoks):
- O (1) algoritm maksab teile 1 operatsiooni
- O (log (n)) algoritm maksab teile 14 operatsiooni
- O (n) algoritm maksab teile 1 000 000 operatsiooni
- O (n * log (n)) algoritm maksab teile 14 000 000 operatsiooni
- O (n2) algoritm maksab teile 1 000 000 000 000 operatsiooni
Ma ei ole arvutusi teinud, aga ma ĂŒtleksin, et O (n2) algoritmiga on teil aega kohvi juua (isegi kaks!). Kui lisate veel 0 andmemahule, on teil aega uinuda.
LĂ€heme sĂŒgavamale
Teabe jaoks:
- Heas hash-tabelis leidmine leiab elemendi O (1) ajaga.
- HĂ€sti tasakaalustatud puus leidmine annab tulemuse O (log (n)) ajaga.
- Massiivis leidmine annab tulemuse O (n) ajaga.
- Parimatel sortimisalgoritmidel on keerukus O (n * log (n)).
- Halval sortimisalgoritmil on keerukus O (n2).
MÀrkus: jÀrgmistes osades vaatame neid algoritme ja andmestruktuure.
On mitu algoritmi ajaliselt keerulist tĂŒĂŒpi:
- keskmise stsenaariumi korral
- parima arengusena
- ja halvim stsenaarium
Ajaliselt keerukus on sageli halvim stsenaarium.
Ma rÀÀkisin ainult algoritmi ajalisest keerukusest, kuid keerukus kehtib ka:
- algoritmi mÀlu kasutus
- algoritmi ketta sisendi / vÀljundi kasutus
Muidugi on keerukusi, mis on halvemad kui nÂČ, nĂ€iteks:
- nâŽ: see on kohutav! MĂ”ned mainitud algoritmid omavad sellist keerukust.
- 3n: see on veel hullem! Ăks algoritm, mida me nĂ€eme artikli keskosas, omab seda keerukust (ja seda kasutatakse tĂ”eliselt paljude andmebaaside puhul).
- faktoriaal n: te ei saa oma tulemusi isegi vÀikese andmehulgaga.
- nn: kui te puutute kokku selle keerukusega, peaksite kĂŒsima endalt, kas see on tĂ”esti teie ala ...
MĂ€rkus: ma andsin teile mitte reaalse mÀÀratletud «suur O» tĂ€henduse, vaid lihtsalt idee. VĂ”ite lugeda seda artiklit reaalse (asĂŒmptootilise) mÀÀratluse jaoks.
MergeSort (Sorteerimine ĂŒhendamisega)
Mida teete, kui peate kollektsiooni sorteerima? Mida? Kutsute vÀlja funktsiooni sort () ... Okei, hea vastus ... Kuid andmebaaside jaoks peate mÔistma, kuidas see sort () funktsioon töötab.
On mitmeid hĂ€id sorteerimisalgoritme, seega keskendun kĂ”ige olulisemale: ĂŒhendamisega sorteerimine. VĂ”ib-olla te ei saa hetkel aru, miks andmete sorteerimine on kasulik, kuid peate selle mĂ”istma pĂ€rast kĂŒsimuste optimeerimise osale pĂŒhendatud osa. Veelgi enam, ĂŒhendamisega sorteerimise mĂ”istmine aitab meil hiljem mĂ”ista andmebaaside ĂŒldoperatsiooni, mida nimetatakse merge join (ĂŒhendamine ĂŒhendamisega).
Merge (ĂŒhendamine)
Nagu paljude kasulike algoritmide puhul, pĂ”hineb ĂŒhendamisega sorteerimine nipil: kahe suurusega N/2 jĂ€rjestatud massiivi ĂŒhendamine N-elementseks jĂ€rjestatud massiiviks maksab vaid N toimingut. Seda toimingut nimetatakse ĂŒhendamiseks.
Vaadake, mida see lihtsa nÀite pÔhjal tÀhendab:

Selles joonises on nĂ€ha, et 8 elemendi lĂ”pliku jĂ€rjestatud massiivi loomiseks peate lihtsalt kordama ĂŒks kord kahes 4-elementises massiivis. Kuna mĂ”lemad 4-elementilised massiivid on juba jĂ€rjestatud:
- 1) te vÔrdlete kahte praegust elementi kahes massiivis (alguses praegune = esimene)
- 2) seejÀrel vÔtke kÔige vÀiksem, et paigutada see 8-elemendiliseks massiiviks
- 3) ja minge jÀrgmisele elemendile massiivis, kus vÔtsite kÔige vÀiksema elemendi
- ja korrake 1,2,3, kuni jĂ”uate ĂŒhe massiivi viimase elemendini.
- Siis vĂ”tate ĂŒlejÀÀnud elemendid teisest massiivist, et paigutada need 8-elemendiliseks massiiviks.
See töötab, kuna mÔlemad 4-elemendilised massiivid on sorteeritud ja seega ei pea te nende massiivide puhul "tagasi minema".
NĂŒĂŒd, kui me mĂ”istsime seda trikki, on siin minu pseudokood merge jaoks:
massiiv mergeSort(massiiv a)
kui (length(a)==1)
tagasta a[0];
lÔpeta kui
//rekursiivsed kÔned
[left_array right_array] := split_into_2_equally_sized_arrays(a);
massiiv new_left_array := mergeSort(left_array);
massiiv new_right_array := mergeSort(right_array);
//ĂŒhendamine 2 vĂ€ikest jĂ€rjestatud massiivi suureks
massiiv tulemus := merge(new_left_array,new_right_array);
tagasta tulemus;Merge sort jagab ĂŒlesande vĂ€iksemateks ĂŒlesanneteks ja seejĂ€rel leiab vĂ€iksemate ĂŒlesannete tulemused, et saada algse ĂŒlesande tulemus (mĂ€rkuste jaoks: see tĂŒĂŒp algoritmidest nimetatakse 'jaga ja valitse'). Kui te ei mĂ”ista seda algoritmi, Ă€rge muretsege; ma ei mĂ”istnud seda esimesel korral, kui nĂ€gin. Kui see vĂ”ib teid aidata, nĂ€en seda algoritmi kui kahefasilist algoritmi:
- Jagamisfaas, kus massiiv jagatakse vÀiksemateks massiivideks
- Sorteerimisfaas, kus vĂ€ikesed massiivid ĂŒhendatakse (kasutades ĂŒhendamist), et moodustada suurem massiiv.
Jagamisfaas (Division phase)

Jagamisfaasi etapis jagatakse massiiv kolmes etapis ĂŒheaegsusteks massiivideks. Ametlik sammude arv on log(N) (kuna N=8, log(N) = 3).
Kust ma seda tean?
Ma olen geenius! ĂhesĂ”naga â matemaatika. Idee on see, et iga samm jagab algse massiivi suurust 2-ga. Sammude arv on see, kui mitu korda saate algse massiivi kaheks jagada. See on logaritmi (alusel 2) tĂ€pne mÀÀratlemine.
Sorteerimisfaas (Sorting phase)

Sorteerimisfaasi etapis alustate ĂŒheaegsustest (ĂŒheelemendilised) massiividest. Iga etapi jooksul rakendate mitmeid ĂŒhendamisoperatsioone ja koguhind on N = 8 operatsiooni:
- Esimesel etapil on teil 4 ĂŒhendamist, mis maksavad 2 operatsiooni igaĂŒhe kohta
- Teisel sammul on teil 2 ĂŒhendamist, mis maksavad 4 operatsiooni igaĂŒhe kohta
- Kolmandal sammul on teil 1 ĂŒhendamine, mis maksab 8 operatsiooni
Kuna on olemas log (N) sammu, koguhind N * log(N) operatsiooni.
Merge sort eelised
Miks on see algoritm nii vÔimas?
Sest:
- Sa saad seda muuta, et vÀhendada mÀlu kasutust, nii et sa ei loo uusi massiive, vaid muudad otse sisendmassiiivi.
MĂ€rkus: seda tĂŒĂŒpi algoritme nimetatakse (sortimine ilma tĂ€iendava mĂ€luta).
- Sa saad seda muuta, et kasutada samaaegselt kettaruumi ja vÀikest mÀlu, ilma oluliste kuludeta kettasisendi/vÀljaande peale. Idee on laadida mÀllu ainult need osad, mida parasjagu töödeldakse. See on oluline, kui pead sorteerima mitu gigabaiti suuruse tabeli vaid 100 megabaidise mÀlu puhvri abil.
MĂ€rkus: seda tĂŒĂŒpi algoritme nimetatakse .
- Sa saad seda muuta mitme protsessi/niidi/serveeri jooksutamiseks.
NĂ€iteks on jaotatud sulandumise sortimine ĂŒks peamisi komponente (mis on struktuur suurte andmete seas).
- See algoritm suudab muuta plii kullaks (tÔeliselt!).
Seda sortimisalgoritmi kasutatakse enamikes (kui mitte kÔigis) andmebaasides, kuid see ei ole ainus. Kui soovid rohkem teada saada, saad lugeda seda , mis arutleb andmebaaside tavaliste sortimisalgoritmide plusse ja miinuseid.
Massiiv, Puud ja Hash-tabel
NĂŒĂŒd, kui me mĂ”istame ajakompleksuse ja sortimise ideed, pean ma rÀÀkima sulle 3 andmestruktuurist. See on oluline, kuna need moodustavad kaasaegsete andmebaaside aluse. Ma tutvustan ka mĂ”istet andmebaasi indeks.
Massiiv
Kaks dimensiooniline massiiv on kÔige lihtsam andmestruktuur. Tabelit saab vaadelda kui massiivi. NÀiteks:

See 2-dimensiooniline massiiv on tabel ridade ja veergudega:
- Iga rida esindab ĂŒksust
- Veerud salvestavad omadused, mis kirjeldavad ĂŒksust.
- Iga veerg salvestab kindla tĂŒĂŒbi andmeid (tĂ€isarv, string, kuupĂ€ev âŠ).
Andmete salvestamine ja visualiseerimine on nii mugav, aga kui pead leidma kindla vÀÀrtuse, ei sobi see.
NĂ€iteks, kui soovid leida kĂ”iki poisse, kes töötavad Suurbritannias, pead lĂ€bi vaatama iga rea, et mÀÀrata, kas see rida kuulub Suurbritanniale. See maksab sulle N operatsiooni, kus N â ridade arv, mis pole halb, aga kas on vĂ”imalik kiiremini? NĂŒĂŒd on aeg tutvuda puude struktuuriga.
MĂ€rkus: enamik kaasaegseid andmebaase pakub efektiivset tabelite salvestamist, nagu heap-organized tables ja index-organized tables. See ei muuda aga kiire otsingu probleemi teatud tingimuse leidmiseks veergude grupis.
Andmebaasi puu ja indeks
Binaarne otsingupuu on binaarne puu, millel on eriline omadus, igas sÔlmes olev vÔti peab olema:
- suurem kui kÔik vasakpoolses alampuud hoitavad vÔtmed
- vÀiksem kui kÔik parempoolses alampuud hoitavad vÔtmed
Vaadakem, mida see visuaalselt tÀhendab
Idee

See puu sisaldab N = 15 elementi. Oletame, et otsin 208:
- Alustan juurest, mille vÔti on 136. Kuna 136<208, vaatan 136 parempoolse alampuu poole.
- 398>208, seega vaatan 398 vasakpoolset alampuud.
- 250>208, seega vaatan 250 vasakpoolset alampuud.
- 200<208, seega vaatan 200 parempoolset alampuud. Aga 200-l ei ole parempoolset alampuud, vÀÀrtus ei eksisteeri (sest kui see eksisteeriks, oleks see 200 parempoolses alampuus).
NĂŒĂŒd, ĂŒtleme, et otsin 40
- Alustan juurest, mille vÔti on 136. Kuna 136 > 40, vaatan 136 vasakpoolset alampuud.
- 80 > 40, seega vaatan 80 vasakpoolset alampuud.
- 40= 40, sÔlm eksisteerib. TÔmban sÔlme id, mis on sÔlmes (see ei ole joonisel) ja vaatan tabelist selle identifikaatori jÀrgi.
- SÔlme identifikaatori teadmine vÔimaldab mul teada, kus andmed tabelis asuvad, ja seega pÀÀsen neile kiiresti juurde.
KokkuvÔttes maksavad mÔlemad otsingud mulle puu sees tasemete arvu. Kui loete hoolikalt sulandamise sorteerimise osa, peate mÀrkama, et siin on log (N) taset. Tulemuseks on, otsingu hind log(N), mitte paha!
Naaseme meie probleemile
Aga see on vÀga abstraktne, seega naeme tagasi meie probleemile. Lihtsa tÀisarvu asemel kujutlege stringi, mis esindab kellegi riiki eelmises tabelis. Oletame, et teil on puu, mis sisaldab vÀlja "country" (veerg 3) tabelis:
- Kui soovite teada, kes töötab Ăhendkuningriigis
- otsite puust sĂ”lme, mis esindab Ăhendkuningriiki
- sĂ”lme "UKnode" sees leiate töötajate kirje asukohad Ăhendkuningriigis.
See otsing maksab log(N) operatsiooni asemel N operatsiooni, kui kasutate otse massiivi. See, mida just esitasite, oli andmebaasi indeks.
Sa vĂ”id ehitada indeksipuu mis tahes vĂ€ljade grupile (string, number, 2 stringi, number ja string, kuupĂ€ev ...) seni, kuni sul on vĂ”rdlemise funktsioon vĂ”tmete (st vĂ€ljade gruppide) jaoks, nii et saad mÀÀrata jĂ€rjestuse vĂ”tmete seas (mis kehtib kĂ”igi pĂ”hitĂŒĂŒpide kohta andmebaasis).
B+PuuIndeks
Kuigi see puu töötab hÀsti kindla vÀÀrtuse saamiseks, on olemas SUUR probleem, kui pead saama mitu elementi kahe vÀÀrtuse vahel. See maksab O(N), kuna pead vaatama iga sÔlme puus ja kontrollima, kas see asub nende kahe vÀÀrtuse vahel (nÀiteks jÀrjekorras oleva puu lÀbimisega). Veelgi enam, see operatsioon ei ole mugav kettaseadmestiku jaoks, kuna pead lugema kogu puud. Peame leidma viisi tÔhusalt teostada vahemiku pÀringut. Selle probleemi lahendamiseks kasutavad kaasaegsed andmebaasid modifitseeritud versiooni eelmisest puust, mida nimetatakse B+Puuks. B+Puu puhul:
- ainult kÔige madalamad sÔlmed (lehed) hoidavad teavet (read seotud tabelis)
- ĂŒlejÀÀnud sĂ”lmed on siin selleks, et suunata Ă”igele sĂ”lmele otsimise ajal.

Nagu nĂ€ha, on siin rohkem sĂ”lmi (kaks korda rohkem). TĂ”esti, sul on tĂ€iendavad sĂ”lmed, "otsustamise sĂ”lmed", mis aitavad sul leida Ă”ige sĂ”lme (mis hoiab ridu seotud tabelis). Kuid otsimise keerukus on ikka O(log(N)) (on ainult veel ĂŒks tase). Suur erinevus on selles, et madala taseme sĂ”lmed on seotud nende jĂ€reltulijatega.
Selle B+Puuga, kui otsid vÀÀrtusi vahemikus 40 kuni 100:
- Pead lihtsalt otsima 40 (vÔi lÀhimat vÀÀrtust pÀrast 40, kui 40 ei eksisteeri), nagu tegid eelneva puu puhul.
- Siis kogu 40 jÀreltulijad, kasutades otse viiteid jÀreltulijatele, kuni saavutad 100.
Oletame, et leidsid M jÀreltulijat ja puul on N sÔlme. Konkreetse sÔlme otsimise hind on log(N) sarnaselt eelneva puu puhul. Kuid selle sÔlme saamisel saad M jÀreltulijat M operatsiooniga viidates nende jÀreltulijatele. See otsing maksab ainult M+log(N) operatsioonide arv vÔrreldes N operatsiooniga eelmise puu puhul. Veelgi enam, teil ei ole vaja lugeda kogu puud (ainult M + log (N) sÔlme), mis tÀhendab vÀiksemat ketta kasutust. Kui M on vÀike (nt 200 rida) ja N suur (1 000 000 rida), siis on see SUUR erinevus.
Kuid siin on uus probleem (taaskord!). Kui lisate vÔi eemaldate rea andmebaasist (ja seega seotud B+ puu indeksist):
- peate sÀilitama jÀrjekorra B+ puu sÔlmede vahel, vastasel juhul ei leia te sÔlmi mittesorteeritud puust.
- peate sÀilitama minimaalset vÔimalikku taseme arvu B+ puus, vastasel juhul ajastatud keerukus O(log(N)) muutub O(N).
TeisisĂ”nu, B+ puu peab olema ise jĂ€rjekorras ja tasakaalus. Ănneks on see vĂ”imalik nutikate eemaldamis- ja sisestamisoperatsioonidega. Kuid see on kulukas: B+ puusse sisestamine ja eemaldamine maksab O(log(N)). SeetĂ”ttu olete mĂ”ned teist kuulnud, et liialt palju indeksite kasutamine ei ole vĂ€ga hea mĂ”te. TĂ”epoolest, te aeglustate kiiret rea sisestamist / vĂ€rskendamist / eemaldamist tabelis, kuna andmebaas peab igas indeksis tabeli indekseid vĂ€rskendama kuluka O(log(N)) operatsiooniga. Veelgi enam, indeksite lisamine tĂ€hendab suuremat koormust tehingute haldurile (millest rÀÀgitakse artikli lĂ”pus).
Lisainformatsiooni saamiseks vÔite vaadata artiklit Vikipeedias . Kui soovite nÀidet B+ puu rakendamisest andmebaasis, vaadake ja MySQLi peaarendaja poolt. Need keskenduvad sellele, kuidas InnoDB (MySQLi mootor) hallab indekseid.
MĂ€rkus: lugeja ĂŒtles mulle, et madala taseme optimeerimise tĂ”ttu peab B+ puu olema tĂ€ielikult tasakaalus.
Hash-tabel
Meie viimane oluline andmestruktuur on hash-tabel. See on vĂ€ga kasulik, kui soovite kiiresti vÀÀrtusi otsida. Veelgi enam, hash-tabeli mĂ”istmine aitab meil hiljem mĂ”ista andmebaasi ĂŒldist liitumisoperatsiooni, mida nimetatakse hash-ĂŒhenduseks ( hash join). Seda andmestruktuuri kasutab ka andmebaas mĂ”ne siseasi (nt lukustustabel vĂ”i vahemĂ€lupuhver, nĂ€eme mĂ”lemaid neid kontseptsioone hiljem).
Hash-tabel on andmestruktuur, mis leiab elemendi kiiresti selle vÔtme jÀrgi. Hash-tabeli loomiseks peate mÀÀratlema:
- vÔti oma elementide jaoks
- hash-funktsiooni vÔtmete jaoks. Arvutatud vÔtmete hash'id annavad elementide asukoha (mida nimetatakse sektsioonideks ).
- vÔtmete vÔrdlemiseks funktsiooni. Kui olete leidnud Ôige sektsiooni, peate leidma elemendi, mida otsite, kasutades seda vÔrdlemist.
Lihtne nÀide
Vaatame ĂŒhte selgitavat nĂ€idet:

See hash-tabel sisaldab 10 sektsiooni. Kuna ma olen laisk, olen kujutanud vaid 5 sektsiooni, kuid tean, et olete nutikad, nii et lasen teil 5 teist ise ette kujutada. Kasutasin hash-funktsiooni vÔtme mooduli 10 jÀrgi. TeisisÔnu, hoian alles elemendi vÔtme viimast numbrit, et leida selle sektsioon:
- kui viimane number on 0, satub element sektsiooni 0,
- kui viimane number on 1, satub element sektsiooni 1,
- kui viimane number on 2, satub element sektsioni 2,
- âŠ
VÔrdlemiseks kasutatud funktsioon on lihtsalt kahe tÀisarvu vÔrdlemine.
Oletame, et soovite saada elementi 78:
- Hash-tabel arvutab 78 jaoks hash-koodi, mis on 8.
- Hash-tabel vaatab sektsiooni 8, ja esimene element, mille ta leiab, on 78.
- Ta tagastab teile elemendi 78
- Otsing maksab vaid 2 toimingut (ĂŒks hash-funktsiooni vÀÀrtuse arvutamiseks ja teine elemendi leidmiseks sektsioonis).
NĂŒĂŒd oletame, et soovite saada elementi 59:
- Hash-tabel arvutab 59 jaoks hash-koodi, mis on 9.
- Hash-tabel otsib sektsioonis 9, esimene leitud element on 99. Kuna 99!=59, ei ole element 99 Ôige element.
- Sama loogikat kasutades vÔetakse teine element (9), kolmas (79), ..., viimane (29).
- Elementi ei leitud.
- Otsing maksis 7 toimingut.
Hea hash-funktsioon
Nagu nÀete, sÔltub hinnang sÔltuvalt otsitavast vÀÀrtusest!
Kui nĂŒĂŒd muudan hash-funktsiooni vĂ”tme mooduli 1 000 000 jĂ€rgi (st vĂ”ttes viimased 6 numbrit), siis teine otsing maksab vaid 1 toimingu, kuna sektsioonis 000059 ei ole elemento. Tegelik ĂŒlesanne on leida hea hash-funktsioon, mis loob sektsioone, milles on vĂ€ga vĂ€he elemente..
Minu nÀites on hea hash-funktsiooni leidmine lihtne. Kuid see on lihtne nÀide, hea hash-funktsiooni leidmine on keerulisem, kui vÔtme:
- string (nÀiteks - perekonnanimi)
- 2 stringi (nÀiteks - perekonnanimi ja eesnimi)
- 2 stringi ja kuupĂ€ev (nĂ€iteks - perekonnanimi, eesnimi ja sĂŒnnikuupĂ€ev)
- âŠ
Hea hash-funktsiooniga toimub otsing hash-tabelis O(1) ajaga.
Massiiv vs hash-tabel
Miks mitte kasutada massiivi?
Hmm, hea kĂŒsimus.
- Hash-tabel vĂ”ib olla osaliselt laaditud mĂ€llu, kuid ĂŒlejÀÀnud segmendid vĂ”ivad jÀÀda ketta peale.
- Massiivi puhul peate kasutama mÀlus jÀrjepidevat ruumi. Kui laadite suure tabeli on vÀga keeruline leida piisavalt jÀrjepidevat ruumi.
- Hash-tabeli puhul saate valida vajaliku vÔtme (nÀiteks, riik ja inimese perekonnanimi).
Lisainformatsiooni saamiseks vÔite lugeda artiklit , mis on efektiivne hash-tabeli rakendus; teil ei ole vaja mÔista Java-d, et mÔista selle artikli lÀbivaatatud kontsepte.
Allikas: habr.com
