Cumu Funzionanu e basa di dati relazionali (Part 1)

Ehi Habr! Prestu à a vostra attenzione a traduzzione di l'articulu
"Cumu funziona una basa di dati relazionale".

Quandu si tratta di basa di dati relazionale ùn possu aiutà ma pensu chì qualcosa manca. Sò usati in ogni locu. Ci sò parechje basa di dati dispunibuli, da u picculu è utile SQLite à u putente Teradata. Ma ci sò solu uni pochi articuli chì spiegà cumu funziona a basa di dati. Pudete cercà per sè stessu utilizendu "cumu è u travagliu di basa di dati relazionale" per vede quanti pochi risultati ci sò. Inoltre, sti articuli sò brevi. Sè vo circate l'ultime tecnulugii buzzy (BigData, NoSQL o JavaScript), truverete articuli più approfonditi chì spieghendu cumu funzionanu.

Sò e basa di dati relazionale troppu vechje è troppu noiose per esse spiegate fora di i corsi universitari, i documenti di ricerca è i libri ?

Cumu Funzionanu e basa di dati relazionali (Part 1)

Cum'è sviluppatore, odiu aduprà qualcosa chì ùn capiscu micca. È se e basa di dati sò stati utilizati per più di 40 anni, ci deve esse una ragione. Duranti l'anni, aghju passatu centinaie d'ore per capisce veramente questi strani scatuli neri chì aghju utilizatu ogni ghjornu. basa di dati relazionale assai interessante perchè elli basatu annantu à cuncetti utili è riutilizabili. Sè site interessatu à capisce una basa di dati, ma ùn avete mai avutu u tempu o l'inclinazione per sfondà in stu tema largu, duvete piacè stu articulu.

Ancu se u titulu di stu articulu hè esplicitu, u scopu di stu articulu ùn hè micca di capisce cumu utilizà a basa di dati. Dunque, duvete digià sapè cumu scrive una dumanda di cunnessione simplice è e dumande di basa RAW; altrimenti ùn pudete micca capisce stu articulu. Hè l'unicu chì avete bisognu di sapè, vi spiegheraghju u restu.

Cumincià cù qualchi basi di l'informatica, cum'è a cumplessità di u tempu di l'algoritmi (BigO). Sò chì alcuni di voi odiate stu cuncettu, ma senza ellu ùn puderete micca capisce l'intricacies in a basa di dati. Siccomu questu hè un tema enormu, Mi concentreraghju ciò chì pensu hè impurtante: cumu processa a basa di dati SQL inchiesta. Aghju solu presentà cuncetti basi di basa di daticusì chì à a fine di l'articulu avete una idea di ciò chì passa sottu à u cappucciu.

Siccomu questu hè un articulu longu è tecnicu chì implica assai algoritmi è strutture di dati, pigliate u vostru tempu per leghje. Certi cuncetti ponu esse difficiuli di capiscenu; pudete saltà elli è ancu avè l'idea generale.

Per i più sapienti trà voi, stu articulu hè divisu in 3 parti:

  • Panoramica di i cumpunenti di basa di dati di livellu bassu è altu
  • Panoramica di u Prucessu di Ottimizazione di Query
  • Panoramica di a gestione di a transazzione è di u buffer pool

Torna à i principii

Anni fà (in una galassia luntanu, luntanu...), i sviluppatori anu da sapè esattamente u numeru di operazioni chì codificavanu. Sapianu i so algoritmi è e strutture di dati da u core perchè ùn puderanu micca permette di perdià u CPU è a memoria di i so computer lenti.

In questa parte, vi ricurdaraghju alcuni di sti cuncetti chì sò essenziali per capiscenu a basa di dati. Aghju ancu introduttu u cuncettu indice di basa di dati.

O(1) vs O(n2)

Oghje, parechji sviluppatori ùn anu micca cura di a cumplessità di u tempu di l'algoritmi ... è sò ghjustu!

Ma quandu avete trattatu cù assai dati (ùn parlu micca millaie) o s'è vo luttate in millisecondi, diventa criticu per capisce stu cuncettu. E cum'è pudete imaginà, e basa di dati anu da trattà cù e duie situazioni! Ùn vi farà micca passà più tempu di u necessariu per fà u puntu. Questu ci aiuterà à capisce u cuncettu di ottimisazione basata nantu à i costi più tardi (costu basatu optimisation).

Concepto

A cumplessità di u tempu di l'algoritmu utilizatu per vede quantu tempu un algoritmu duverà per compie per una data quantità di dati. Per discrìviri sta cumplessità, usamu a notazione matematica grande O. Questa notazione hè aduprata cù una funzione chì descrive quante operazioni un algoritmu hà bisognu per un certu numaru di inputs.

Per esempiu, quandu dicu "stu algoritmu hà cumplessità O(some_function())", significa chì l'algoritmu richiede some_function(a_certain_amount_of_data) operazioni per processà una certa quantità di dati.

Cusì hà Ùn hè micca a quantità di dati chì importa **, altrimenti ** cumu u numeru di operazioni aumenta cù u voluminu di dati crescente. A cumplessità di u tempu ùn furnisce micca un numeru esatta di operazioni, ma hè una bona manera di stimà u tempu di esecuzione.

Cumu Funzionanu e basa di dati relazionali (Part 1)

In questu graficu pudete vede u nùmeru di operazioni versus a quantità di dati di input per diversi tipi di cumplessità di u tempu di l'algoritmu. Aghju utilizatu una scala logaritmica per vede. In altre parolle, a quantità di dati aumenta rapidamente da 1 à 1 billion. Pudemu vede chì:

  • O (1) o cumplessità custanti ferma custanti (altrimenti ùn saria micca chjamatu cumplessità custanti).
  • O(Scie à(n)) resta bassu ancu cù miliardi di dati.
  • A peor difficultà - O(n2), induve u numeru di operazioni cresce rapidamente.
  • L'altri dui cumplicazioni aumentanu cusì rapidamente.

esempi

Cù una piccula quantità di dati, a diffarenza trà O (1) è O (n2) hè insignificante. Per esempiu, dicemu chì avete un algoritmu chì deve processà 2000 elementi.

  • L'algoritmu O(1) vi costarà 1 operazione
  • L'algoritmu O(log(n)) vi costarà 7 operazioni
  • L'algoritmu O(n) vi costarà 2 000 operazioni
  • L'algoritmu O(n*log(n)) vi costarà 14 000 operazioni
  • L'algoritmu O(n2) vi costarà 4 000 000 operazioni

A sfarenza trà O(1) è O(n2) pari grande (4 milioni di operazioni) ma perderete un massimu di 2 ms, ghjustu u tempu di lampà l'ochji. Infatti, i prucessori muderni ponu processà centinaie di milioni di operazioni per seconda. Hè per quessa chì u rendiment è l'ottimisazione ùn sò micca un prublema in parechji prughjetti IT.

Comu dissi, hè sempre impurtante di cunnosce stu cuncettu quandu u travagliu cù quantità enormi di dati. Se sta volta l'algoritmu hà da processà 1 elementi (chì ùn hè micca tantu per una basa di dati):

  • L'algoritmu O(1) vi costarà 1 operazione
  • L'algoritmu O(log(n)) vi costarà 14 operazioni
  • L'algoritmu O(n) vi costarà 1 operazioni
  • L'algoritmu O(n*log(n)) vi costarà 14 operazioni
  • L'algoritmu O(n2) vi costarà 1 di operazioni

Ùn aghju micca fattu a matematica, ma diceraghju chì cù l'algoritmu O(n2) avete u tempu di beie un caffè (ancu dui !). Sè aghjunghje un altru 0 à u voluminu di dati, avarete tempu per piglià una suesta.

Andemu più in fondu

Per riferimentu:

  • Una bona ricerca di a tavola hash trova un elementu in O (1).
  • A ricerca di un arbre ben equilibratu pruduce risultati in O(log(n)).
  • A ricerca di un array produce risultati in O(n).
  • I meglii algoritmi di classificazione anu cumplessità O(n*log(n)).
  • Un malu algoritmu di classificazione hà cumplessità O(n2).

Nota: In i seguenti parti vi vede sti algoritmi è strutture di dati.

Ci hè parechji tipi di cumplessità di u tempu di l'algoritmu:

  • scenariu di casu mediu
  • u megliu scenariu
  • è u peghju scenariu

A cumplessità di u tempu hè spessu u peghju scenariu.

Parlava solu di a cumplessità di u tempu di l'algoritmu, ma a cumplessità hè ancu appiicata à:

  • u cunsumu di memoria di l'algoritmu
  • Algoritmu di cunsumu I / O di discu

Di sicuru, ci sò cumplicazioni peghju chè n2, per esempiu:

  • n4: questu hè terribili! Certi di l'algoritmi citati anu sta cumplessità.
  • 3n : questu hè ancu peghju ! Unu di l'algoritmi chì vedemu à mezu à questu articulu hà sta cumplessità (è hè veramente utilizatu in parechje basa di dati).
  • factorial n: ùn vi mai arrivare i vostri risultati ancu cù una piccula quantità di dati.
  • nn: Se scontri sta cumplessità, duvete dumandà sè questu hè veramente u vostru campu di attività...

Nota: Ùn aghju micca datu a definizione attuale di a designazione grande O, solu una idea. Pudete leghje stu articulu à Wikipedia per a definizione reale (asintotica).

MergeSort

Chì fate quandu avete bisognu di sorte una cullizzioni? Chì ? Chjamate a funzione sort () ... Ok, bona risposta ... Ma per una basa di dati, duvete capisce cumu funziona sta funzione sort ().

Ci sò parechji boni algoritmi di sorte, cusì mi cuncintraraghju nantu à u più impurtante: fusione sorte. Ùn pudete micca capisce perchè i dati di sorte sò utili avà, ma duvete dopu a parte di ottimisazione di a dumanda. Inoltre, capiscenu a sorta di fusione ci aiuterà più tardi à capisce l'operazione cumuni di unisce à a basa di dati chjamata mischjà Unete (associazione di fusione).

Unisce

Cum'è parechji algoritmi utili, a sorta di fusione si basa in un truccu: cumminendu 2 matrici ordinati di taglia N / 2 in un array ordinatu di N elementi custa solu N operazioni. Questa operazione hè chjamata fusione.

Videmu ciò chì questu significa cun un esempiu simplice:

Cumu Funzionanu e basa di dati relazionali (Part 1)

Questa figura mostra chì per custruisce l'array finale di 8 elementi, avete solu bisognu di iterà una volta nantu à i 2 arrays di 4 elementi. Siccomu i dui matrici di 4 elementi sò digià ordinati:

  • 1) paragunate i dui elementi attuali in dui matrici (à u principiu currente = prima)
  • 2) poi pigliate u più chjucu per mette in un array di 8 elementi
  • 3) è andate à l'elementu prossimu in u array induve avete pigliatu l'elementu più chjucu
  • è ripetite 1,2,3 finu à ghjunghje à l'ultimu elementu di una di e matrici.
  • Allora pigliate l'elementi rimanenti di l'altru array per mette in un array di 8 elementi.

Questu funziona perchè i dui arrays di 4 elementi sò ordinati è cusì ùn avete micca "torna" in quelli arrays.

Avà chì avemu capitu u truccu, eccu u mo pseudocode per fusione:

array mergeSort(array a)
   if(length(a)==1)
      return a[0];
   end if

   //recursive calls
   [left_array right_array] := split_into_2_equally_sized_arrays(a);
   array new_left_array := mergeSort(left_array);
   array new_right_array := mergeSort(right_array);

   //merging the 2 small ordered arrays into a big one
   array result := merge(new_left_array,new_right_array);
   return result;

Merge sort rompe un prublema in prublemi più chjuchi è poi trova i risultati di i prublemi più chjuchi per ottene u risultatu di u prublema originale (nota: stu tipu d'algoritmu hè chjamatu divide and conquer). Se ùn avete micca capitu stu algoritmu, ùn vi preoccupate; Ùn aghju micca capitu a prima volta chì l'aghju vistu. Se vi pò aiutà, vecu questu algoritmu cum'è un algoritmu in dui fasi:

  • Fase di divisione, induve l'array hè divisu in arrays più chjuchi
  • A fase di classificazione hè induve i picculi array sò cumminati (usendu l'unione) per furmà un array più grande.

Fase di divisione

Cumu Funzionanu e basa di dati relazionali (Part 1)

In a tappa di divisione, l'array hè divisu in array unitari in 3 passi. U numaru formale di passi hè log (N) (poi N = 8, log (N) = 3).

Cumu a so?

Sò geniu ! In una parolla - matematica. L'idea hè chì ogni passu divide a dimensione di l'array originale da 2. U numaru di passi hè u numeru di volte chì pudete dividisce l'array originale in dui. Questa hè a definizione esatta di un logaritmu (base 2).

Fase di classificazione

Cumu Funzionanu e basa di dati relazionali (Part 1)

In a fase di classificazione, cuminciate cù arrays unitaria (elementu unicu). Durante ogni passu applicate parechje operazioni di fusione è u costu tutale hè N = 8 operazioni:

  • In u primu stadiu avete 4 fusioni chì costanu 2 operazioni ognunu
  • In u sicondu passu avete 2 fusioni chì costanu 4 operazioni ognunu
  • In u terzu passu avete 1 fusione chì costa 8 operazioni

Siccomu ci sò log (N) passi, costu tutale N * log(N) operazioni.

Vantaghji di a sorta di fusione

Perchè questu algoritmu hè cusì putente?

Perchè:

  • Pudete cambià per riduce l'impronta di memoria in modu chì ùn create micca novi matrici ma mudificà direttamente l'array di input.

Nota: stu tipu d'algoritmu hè chjamatu in-postu (selezione senza memoria supplementare).

  • Pudete cambià per utilizà u spaziu di discu è una piccula quantità di memoria à u stessu tempu senza incurrence un discu I / O overhead significativu. L'idea hè di carricà in memoria solu quelli parti chì sò attualmente processati. Questu hè impurtante quandu avete bisognu di sorte una tavola multi-gigabyte cù solu un buffer di memoria di 100 megabyte.

Nota: stu tipu d'algoritmu hè chjamatu sorta esterna.

  • Pudete cambià per eseguisce in parechje prucessi / fili / servitori.

Per esempiu, a sorta di fusione distribuita hè unu di i cumpunenti chjave Hadoop (chì hè una struttura in big data).

  • Stu algoritmu pò turnà u piombo in oru (veramente!).

Stu algoritmu di sorte hè utilizatu in a maiò parte (se micca in tutti) di basa di dati, ma ùn hè micca l'unicu. Se vulete sapè di più, pudete leghje questu travagliu di ricerca, chì discute i vantaghji è i contra di l'algoritmi di ordinazione di basa di dati cumuni.

Array, Tree and Hash Table

Avà chì avemu capitu l'idea di a cumplessità di u tempu è di a classificazione, vi duverebbe dì circa 3 strutture di dati. Questu hè impurtante perchè elli sò a basa di basa di dati muderni. Aghju ancu introduttu u cuncettu indice di basa di dati.

Array

Un array bidimensionale hè a struttura di dati più simplice. Una tavola pò esse pensata cum'è un array. Per esempiu:

Cumu Funzionanu e basa di dati relazionali (Part 1)

Questa matrice bidimensionale hè una tavola cù fila è colonne:

  • Ogni linea rapprisenta una entità
  • I culonni almacenanu pruprietà chì descrizanu l'entità.
  • Ogni culonna guarda dati di un tipu specificu (integer, string, data...).

Questu hè cunvenutu per almacenà è visualizà e dati, però, quandu avete bisognu di truvà un valore specificu, questu ùn hè micca adattatu.

Per esempiu, sè vo vulete truvà tutti i picciotti chì travaglianu in u Regnu Unitu, avete bisognu di guardà ogni fila per stabilisce se quella fila appartene à u Regnu Unitu. Vi costarà N transaccionesinduve N - numeru di linii, chì ùn hè micca male, ma puderia esse un modu più veloce? Avà hè u tempu per noi di cunnosce l'arburi.

Nota: A maiò parte di e basa di dati muderni furniscenu array estesi per almacenà e tabelle in modu efficiente: tabelle organizzate in heap è tabelle organizzate in indici. Ma questu ùn cambia micca u prublema di truvà rapidamente una cundizione specifica in un gruppu di colonne.

Arburu di basa di dati è index

Un arbre di ricerca binariu hè un arbre binariu cù una pruprietà speciale, a chjave in ogni nodu deve esse:

  • più grande di tutte e chjave guardate in u subtree di manca
  • menu di tutte e chjave cullucate in u subtree ghjustu

Videmu ciò chì questu significa visualmente

Idea

Cumu Funzionanu e basa di dati relazionali (Part 1)

Questu arburu hà N = 15 elementi. Diciamu chì cercu 208:

  • Accuminciamu da a radica chì a chjave hè 136. Dapoi 136 <208, aghju fighjulatu u subtree right di u node 136.
  • 398>208 dunque stanu à fighjulà u subtree left di u node 398
  • 250>208 dunque stanu à fighjulà u subtree left di u node 250
  • 200 <208, per quessa, aghju fighjulatu u subtree right di u node 200. Ma 200 ùn hà micca un subtree right, valore ùn esiste micca (perchè s'ellu esiste, serà in u subtree right 200).

Avà dicemu chì cercu 40

  • Accuminciamu da a radica chì a chjave hè 136. Dapoi 136> 40, aghju fighjulatu u subtree left di u node 136.
  • 80> 40, dunque stanu à fighjulà u subtree left di u node 80
  • 40 = 40, nodu esiste. Recuperu l'ID di fila in u node (micca mostratu in a stampa) è cercate in a tavula l'ID di fila datu.
  • Sapendu l'ID di fila mi permette di sapè esattamente induve sò i dati in a tavula, perchè possu ricuperà istantaneamente.

In fine, e duie ricerche mi costaranu u numeru di livelli in l'arbulu. Se leghjite a parte nantu à a sorta di fusione cù cura, duvete vede chì ci sò livelli di log (N). Ne risulta, logu di costu di ricerca (N), micca male!

Riturnemu à u nostru prublema

Ma questu hè assai astrattu, allora vultemu à u nostru prublema. Invece di un integer simplice, imagine una stringa chì rapprisenta u paese di qualchissia in a tavula precedente. Diciamu chì avete un arbre chì cuntene u campu "paese" (colonna 3) di a tavula:

  • Se vulete sapè quale travaglia in u Regnu Unitu
  • fighjate à l'arbulu pè ottene u node chì rapprisenta Gran Bretagna
  • Dentru "UKnode" truverete u locu di i registri di i travagliadori di u Regnu Unitu.

Questa ricerca costarà log (N) operazioni invece di N operazioni se utilizate l'array direttamente. Ciò chì avete appena presentatu era indice di basa di dati.

Pudete custruisce un arbulu d'indici per ogni gruppu di campi (stringa, numeru, 2 linee, numeru è stringa, data...) sempre chì avete una funzione per paragunà e chjave (ie gruppi di campi) per pudè stabilisce. ordine trà e chjave (chì hè u casu per qualsiasi tippi basi in a basa di dati).

B + TreeIndex

Mentre chì questu arburu travaglia bè per ottene un valore specificu, ci hè un BIG prublema quandu avete bisognu ottene parechji elementi trà dui valori. Questu custarà O (N) perchè duverete guardà ogni nodu in l'arburu è verificate s'ellu hè trà sti dui valori (per esempiu, cù un traversu urdinatu di l'arburu). Inoltre, sta operazione ùn hè micca amichevule per l'I / O di discu, postu chì avete da leghje l'arburu sanu. Avemu bisognu di truvà un modu per eseguisce in modu efficiente dumanda di gamma. Per risolve stu prublema, e basa di dati muderni utilizanu una versione mudificata di l'arburu precedente chjamatu B + Tree. In un arbre B + Tree:

  • solu i nodi più bassi (foglie) magazzini infurmazione (locu di e fila in a tavula ligata)
  • u restu di i nodi sò quì per u routing à u node currettu durante a ricerca.

Cumu Funzionanu e basa di dati relazionali (Part 1)

Comu pudete vede, ci sò più nodi quì (duie volte). In verità, avete nodi supplementari, "nodi di decisione", chì vi aiuterà à truvà u node currettu (chì guarda u locu di e fila in a tabella assuciata). Ma a cumplessità di ricerca hè sempre O (log (N)) (ci hè solu un livellu più). A grande diferenza hè chì i nodi à u livellu più bassu sò cunnessi cù i so successori.

Cù questu B + Tree, sè vo circate valori trà 40 è 100:

  • Solu bisognu di circà 40 (o u valore più vicinu dopu à 40 se 40 ùn esiste micca) cum'è avete fattu cù l'arburu precedente.
  • Allora cullate 40 eredi aduprendu ligami eredi diretti finu à ghjunghje à 100.

Dicemu chì truvate M successori è l'arbulu hà N nodi. Truvà un nodu specificu custa log (N) cum'è l'arburu precedente. Ma una volta uttene stu nodu, uttene M successori in operazioni M cù referenze à i so successori. Questa ricerca costa solu M+log(N) operazioni paragunate à N operazioni nantu à l'arburu precedente. Inoltre, ùn avete micca bisognu di leghje l'arburu sanu (solu M + log (N) nodes), chì significa menu usu di discu. Se M hè chjuca (per esempiu 200 fila) è N hè grande (1 fila), ci sarà una GRANDE differenza.

Ma ci sò novi prublemi quì (di novu!). Se aghjunghje o sguassate una fila in a basa di dati (è dunque in l'indice B + Tree assuciatu):

  • duvete mantene l'ordine trà i nodi in un B + Tree, altrimenti ùn sarete micca capaci di truvà i nodi in un arbulu senza classificazione.
  • duvete mantene u minimu numeru pussibule di livelli in B + Tree, altrimenti a cumplessità di u tempu O (log (N)) diventa O (N).

In altri palori, B + Tree deve esse auto-ordine è equilibratu. Per furtuna, questu hè pussibule cù operazioni intelligenti di sguassà è inserisce. Ma questu vene à un costu: l'inserzioni è l'eliminazioni in un arbre B+ costanu O(log(N)). Hè per quessa chì alcuni di voi l'anu intesu aduprà troppu indici ùn hè micca una bona idea. Veramente, vi rallenta l'inserzione / aghjurnamentu / eliminazione rapida di una fila in una tavulaperchè a basa di dati deve aghjurnà l'indici di a tavula utilizendu una operazione O(log(N)) caru per ogni indice. Inoltre, aghjunghje indici significa più carichi di travagliu per gestore di transazzione (sarà descritta à a fine di l'articulu).

Per più dettagli, pudete vede l'articulu di Wikipedia nantu B+Arburu. Se vulete un esempiu di implementazione di B + Tree in una basa di dati, fate un ochju stu articulu и stu articulu da un principale sviluppatore MySQL. Tramindui si cuncentranu nantu à cumu InnoDB (u mutore MySQL) gestisce l'indici.

Nota: Un lettore m'hà dettu chì, per via di ottimisazioni di livellu bassu, l'arbulu B + deve esse cumpletamente equilibratu.

Hashtable

A nostra ultima struttura di dati impurtante hè a table hash. Questu hè assai utile quandu vulete cercà rapidamente i valori. Inoltre, capiscenu una tabella di hash ci aiuterà più tardi à capisce una operazione cumuna di unione di basa di dati chjamata hash join ( hash join). Sta struttura di dati hè ancu aduprata da a basa di dati per almacenà alcune cose internu (per esempiu. tavula di serratura o piscina tampone, videremu issi dui cuncetti dopu).

Un hash table hè una struttura di dati chì trova rapidamente un elementu da a so chjave. Per custruisce una tavola hash avete bisognu di definisce:

  • clue per i vostri elementi
  • funzione hash per i chjavi. L'hash di chjave calculatu dà u locu di l'elementi (chjamati segmenti ).
  • funzione per paragunà e chjave. Una volta chì avete trovu u segmentu currettu, duvete truvà l'elementu chì cercate in u segmentu utilizendu sta paragone.

Esempiu simplice

Pigliemu un esempiu chjaru:

Cumu Funzionanu e basa di dati relazionali (Part 1)

Questa tavola hash hà 10 segmenti. Perchè sò pigra, aghju stampatu solu 5 segmenti, ma sò chì site intelligente, cusì vi lascio imagine l'altri 5 da sè stessu. Aghju utilizatu una funzione hash modulo 10 di a chjave. In altre parolle, aghju guardatu solu l'ultimu cifru di a chjave di l'elementu per truvà u so segmentu:

  • se l'ultimu cifru hè 0, l'elementu cade in u segmentu 0,
  • se l'ultimu cifru hè 1, l'elementu cade in u segmentu 1,
  • se l'ultimu cifru hè 2, l'elementu cade in l'area 2,
  • ...

A funzione di paragone chì aghju utilizatu hè simplicemente ugualità trà dui interi.

Diciamu chì vulete ottene l'elementu 78:

  • A tavola hash calcula u codice hash per 78, chì hè 8.
  • A tavula di hash vede u segmentu 8, è u primu elementu chì trova hè 78.
  • Ella torna l'articulu 78 à voi
  • A ricerca costa solu 2 operazioni (unu per calculà u valore di hash è l'altru per circà l'elementu in u segmentu).

Avà dicemu chì vulete uttene l'elementu 59:

  • A tavola hash calcula u codice hash per 59, chì hè 9.
  • A tavola hash cerca in u segmentu 9, u primu elementu truvatu hè 99. Dapoi 99! = 59, l'elementu 99 ùn hè micca un elementu validu.
  • Utilizendu a listessa logica, u sicondu elementu (9), u terzu (79), ..., l'ultimu (29) sò pigliati.
  • Elementu micca trovu.
  • A ricerca costa 7 operazioni.

Bona funzione hash

Comu pudete vede, secondu u valore chì vo circate, u costu ùn hè micca listessu !

Se aghju cambiatu a funzione hash modulo 1 di a chjave (vale à dì, pigliendu l'ultimi 000 cifre), a seconda ricerca costa solu 000 operazione postu chì ùn ci hè micca elementi in u segmentu 6. U veru sfida hè di truvà una bona funzione di hash chì creà buckets chì cuntenenu un pocu numeru di elementi.

In u mo esempiu, truvà una bona funzione hash hè faciule. Ma questu hè un esempiu simplice, truvà una bona funzione hash hè più difficiule quandu a chjave hè:

  • stringa (per esempiu - cognome)
  • 2 linee (per esempiu - cognome è nome)
  • 2 linee è data (per esempiu - cognome, nome è data di nascita)
  • ...

Cù una bona funzione di hash, e ricerche di tavule di hash costanu O (1).

Array vs hash table

Perchè ùn aduprà un array?

Hmm, bona dumanda.

  • A tavola di hash pò esse parzialmente caricatu in memoria, è i segmenti restante ponu stà nantu à u discu.
  • Cù un array duvete aduprà u spaziu contigu in memoria. Sè vo caricate una grande tavola hè assai difficiuli di truvà abbastanza spaziu cuntinuu.
  • Per un hash table, pudete selezziunate a chjave chì vulete (per esempiu, paese è cognome di a persona).

Per più infurmazione, pudete leghje l'articulu circa JavaHashMap, chì hè una implementazione efficace di una tavola hash; ùn avete micca bisognu di capisce Java per capisce i cuncetti trattati in questu articulu.

Source: www.habr.com

Add a comment