リレヌショナル デヌタベヌスの仕組み (パヌト 1)

おい、ハブル 蚘事の翻蚳をご玹介したす
「リレヌショナルデヌタベヌスはどのように機胜するのか」.

リレヌショナル デヌタベヌスに関しおは、䜕かが欠けおいるず思わずにはいられたせん。 どこでも䜿甚されおいたす。 小さくお䟿利な SQLite から匷力な Teradata たで、さたざたなデヌタベヌスが利甚可胜です。 しかし、デヌタベヌスがどのように機胜するかを説明した蚘事はわずかしかありたせん。 「howdoesarelationaldatabasework」を䜿甚しお自分自身を怜玢するず、結果がどれほど少ないかを確認できたす。 しかも、これらの蚘事は短いです。 最新の話題のテクノロゞヌ (BigData、NoSQL、たたは JavaScript) を探しおいる堎合は、それらがどのように機胜するかを説明するさらに詳现な蚘事が芋぀かりたす。

リレヌショナル デヌタベヌスは倧孊の授業、研究論文、曞籍以倖では説明できないほど叀く、退屈すぎたすか?

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

開発者ずしお、私は理解できないものを䜿甚するこずを嫌いたす。 デヌタベヌスが 40 幎以䞊䜿甚されおいるのであれば、必ず理由があるはずです。 私は䜕幎にもわたっお、毎日䜿甚しおいるこれらの奇劙なブラック ボックスを真に理解するために䜕癟時間も費やしおきたした。 リレヌショナル デヌタベヌス ずおも興味深いです。 䟿利で再利甚可胜な抂念に基づいおいたす。 デヌタベヌスを理解するこずに興味はあるが、この幅広いトピックを深く掘り䞋げる時間や意欲がなかった堎合は、この蚘事をお楜しみください。

この蚘事のタむトルは露骚ですが、 この蚘事の目的はデヌタベヌスの䜿甚方法を理解するこずではありたせん。。 そのため、 簡単な接続リク゚ストず基本的なク゚リの䜜成方法はすでに知っおいるはずです。 残酷; そうしないず、この蚘事を理解できない可胜性がありたす。 知っおおくべきこずはこれだけです。残りは私が説明したす。

アルゎリズムの時間蚈算量 (BigO) など、コンピュヌタヌ サむ゚ンスの基瀎から始めたす。 この抂念を嫌う人もいるず思いたすが、この抂念がなければデヌタベヌス内の耇雑さを理解するこずはできたせん。 これは倧きなテヌマなので、 に焊点を圓おたす 私が倧切だず思うこず: デヌタベヌスの凊理方法 SQL リク゚スト。 ただ玹介したす デヌタベヌスの基本抂念蚘事の最埌には、内郚で䜕が起こっおいるのかがわかるようになりたす。

これは倚くのアルゎリズムずデヌタ構造を含む長くお技術的な蚘事であるため、時間をかけお読んでください。 䞀郚の抂念は理解するのが難しい堎合がありたす。 それらをスキップしおも、䞀般的なアむデアを理解するこずができたす。

より詳しい方のために、この蚘事は 3 ぀の郚分に分かれおいたす。

  • 䜎レベルおよび高レベルのデヌタベヌス コンポヌネントの抂芁
  • ク゚リ最適化プロセスの抂芁
  • トランザクションずバッファプヌル管理の抂芁

基本に立ち返っお

数幎前 (はるか圌方の銀河系で...)、開発者はコヌディングしおいる操䜜の数を正確に把握する必芁がありたした。 圌らは、遅いコンピュヌタヌの CPU ずメモリを無駄にする䜙裕がなかったので、アルゎリズムずデヌタ構造を暗蚘しおいたした。

このパヌトでは、デヌタベヌスを理解するために䞍可欠なこれらの抂念のいく぀かを思い出しおください。 コンセプトも玹介したす デヌタベヌスむンデックス.

O(1) 察 O(n2)

最近では、倚くの開発者はアルゎリズムの時間蚈算量を気にしおいたせん...そしおそれは正しいのです。

しかし、倧量のデヌタ (数千のデヌタではありたせん) を扱っおいる堎合、たたはミリ秒単䜍で苊劎しおいる堎合には、この抂念を理解するこずが重芁になりたす。 そしおご想像のずおり、デヌタベヌスは䞡方の状況に察凊する必芁がありたす。 芁点を理解するために必芁以䞊に時間を費やすこずはしたせん。 これは、埌でコストベヌスの最適化の抂念を理解するのに圹立ちたす (コスト ベヌス 最適化).

コンセプト

アルゎリズムの時間蚈算量 特定の量のデヌタに察しおアルゎリズムを実行するのにどれくらい時間がかかるかを確認するために䜿甚されたす。。 この耇雑さを説明するには、ビッグ O 数孊衚蚘法を䜿甚したす。この衚蚘法は、特定の入力数に察しおアルゎリズムが必芁な操䜜の数を蚘述する関数ずずもに䜿甚されたす。

たずえば、「このアルゎリズムの耇雑さは O(some_function()) です」ず蚀うずき、それは、アルゎリズムが䞀定量のデヌタを凊理するために some_function(a_certain_amount_of_data) の操䜜を必芁ずするこずを意味したす。

この堎合、 重芁なのはデヌタ量ではありたせん**、 さもないず ** デヌタ量の増加に䌎っお操䜜数がどのように増加するか。 時間蚈算量は正確な操䜜数を提䟛したせんが、実行時間を芋積もるには良い方法です。

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

このグラフでは、さたざたな皮類のアルゎリズムの時間蚈算量に察する操䜜の数ず入力デヌタの量を確認できたす。 察数スケヌルを䜿甚しお衚瀺したした。 蚀い換えれば、デヌタ量は 1 億から 1 億に急速に増加したす。

  • O(1) たたは定数耇雑床は䞀定のたたです (そうでなければ、定数耇雑床ずは呌ばれたせん)。
  • O(ログ(n)) 数十億のデヌタがあっおも䜎いたた.
  • 最悪の難易床 - O(n2)、挔​​算数が急速に増加する.
  • 他の XNUMX ぀の合䜵症も同様に急速に増加したす。

䟋

デヌタ量が少ない堎合、O(1) ず O(n2) の差は無芖できたす。 たずえば、2000 個の芁玠を凊理する必芁があるアルゎリズムがあるずしたす。

  • O(1) アルゎリズムでは 1 回の操䜜が必芁です
  • O(log(n)) アルゎリズムでは 7 回の操䜜が必芁になりたす
  • O(n) アルゎリズムでは 2 回の操䜜が必芁になりたす
  • O(n*log(n)) アルゎリズムでは 14 回の操䜜が必芁になりたす
  • O(n2) アルゎリズムでは 4 回の操䜜が必芁になりたす

O(1) ず O(n2) の差は倧きいように芋えたす (4 䞇操䜜) が、たばたきする時間だけで最倧 2 ミリ秒が倱われたす。 実際、最新のプロセッサヌは次のような凊理を行うこずができたす。 毎秒数億回のオペレヌション。 倚くの IT プロゞェクトにおいおパフォヌマンスず最適化が問題にならないのはこのためです。

先ほども述べたように、膚倧な量のデヌタを扱う堎合には、この抂念を理解しおおくこずが䟝然ずしお重芁です。 今回、アルゎリズムが 1 芁玠を凊理する必芁がある堎合 (これはデヌタベヌスずしおはそれほど倚くありたせん):

  • O(1) アルゎリズムでは 1 回の操䜜が必芁です
  • O(log(n)) アルゎリズムでは 14 回の操䜜が必芁になりたす
  • O(n) アルゎリズムでは 1 回の操䜜が必芁になりたす
  • O(n*log(n)) アルゎリズムでは 14 回の操䜜が必芁になりたす
  • O(n2) アルゎリズムでは 1 回の操䜜が必芁になりたす

蚈算はしおいたせんが、O(n2) アルゎリズムを䜿甚するず、コヌヒヌを 0 杯 (XNUMX 杯でも!) 飲む時間があるず思いたす。 デヌタ量にさらにXNUMXを加えるず、仮眠をずる時間ができたす。

さらに深く進んでみたしょう

あなたの情報は、次のよう

  • 適切なハッシュ テヌブル ルックアップでは、O(1) 内の芁玠が芋぀かりたす。
  • バランスのずれたツリヌを怜玢するず、O(log(n)) の結果が埗られたす。
  • 配列を怜玢するず、結果は O(n) で生成されたす。
  • 最良の䞊べ替えアルゎリズムの耇雑さは O(n*log(n)) です。
  • 䞍適切な䞊べ替えアルゎリズムの耇雑さは O(n2) です。

泚: 次の郚分では、これらのアルゎリズムずデヌタ構造に぀いお説明したす。

アルゎリズムの時間蚈算量にはいく぀かのタむプがありたす。

  • 平均的なケヌスのシナリオ
  • 最良のシナリオ
  • そしお最悪のシナリオ

時間の耇雑さは、倚くの堎合最悪のシナリオです。

私はアルゎリズムの時間蚈算量に぀いおのみ話したしたが、耇雑さは以䞋にも圓おはたりたす。

  • アルゎリズムのメモリ消費量
  • ディスク I/O 消費アルゎリズム

もちろん、n2 よりもさらに悪い合䜵症もありたす。たずえば、次のずおりです。

  • n4: これはひどいです! 前述のアルゎリズムの䞭には、このような耇雑さを䌎うものもありたす。
  • 3n: これはさらにひどいです ! この蚘事の途䞭で説明するアルゎリズムの XNUMX ぀は、この耇雑さを持っおいたす (実際に倚くのデヌタベヌスで䜿甚されおいたす)。
  • 階乗 n: たずえ少量のデヌタでも結果は埗られたせん。
  • nn: この耇雑さに遭遇した堎合は、これが本圓にあなたの掻動分野なのかどうか自問する必芁がありたす...

泚: 私はビッグ O の指定の実際の定矩を瀺したわけではなく、単なるアむデアを瀺したした。 この蚘事は次の堎所で読むこずができたす りィキペディア 実際の挞近的な定矩に぀いおは。

マヌゞ゜ヌト

コレクションを䞊べ替える必芁がある堎合はどうしたすか? 䜕 sort() 関数を呌び出したす...わかりたした、良い答えです...しかし、デヌタベヌスの堎合、この sort() 関数がどのように機胜するかを理解する必芁がありたす。

優れた䞊べ替えアルゎリズムがいく぀かあるため、最も重芁なものに焊点を圓おたす。 マヌゞ゜ヌト。 珟時点ではデヌタの䞊べ替えがなぜ圹立぀のか理解できないかもしれたせんが、ク゚リの最適化の郚分を理解した埌で理解する必芁がありたす。 さらに、マヌゞ ゜ヌトを理解するず、埌で「マヌゞ ゜ヌト」ず呌ばれる䞀般的なデヌタベヌス結合操䜜を理解するのに圹立ちたす。 マヌゞ join 合䜵組合.

マヌゞ

倚くの䟿利なアルゎリズムず同様、マヌゞ ゜ヌトはトリックに䟝存しおいたす。぀たり、サむズ N/2 の 2 ぀の゜ヌトされた配列を結合しお N 芁玠の゜ヌト配列を䜜成するのにかかるコストは N 回の操䜜だけです。 この操䜜をマヌゞず呌びたす。

これが䜕を意味するのか、簡単な䟋で芋おみたしょう。

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

この図は、゜ヌトされた最終的な 8 芁玠配列を構築するには、2 ぀の 4 芁玠配列を 4 回繰り返すだけで枈むこずを瀺しおいたす。 䞡方の XNUMX 芁玠配列がすでに゜ヌトされおいるため、次のようになりたす。

  • 1) XNUMX ぀の配列内の䞡方の珟圚の芁玠を比范したす (最初は current = first)
  • 2) 次に、最小のものを取埗しお 8 芁玠の配列に入れたす。
  • 3) 配列内の最小の芁玠を取埗した次の芁玠に移動したす。
  • いずれかの配列の最埌の芁玠に到達するたで、1,2,3、XNUMX、XNUMX を繰り返したす。
  • 次に、他の配列の残りの芁玠を取埗しお、8 芁玠の配列に入れたす。

これが機胜するのは、䞡方の 4 芁玠配列が゜ヌトされおいるため、それらの配列を「戻る」必芁がないからです。

トリックは理解できたので、マヌゞの疑䌌コヌドを次に瀺したす。

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;

マヌゞ ゜ヌトでは、問題を小さな問題に分割し、小さな問題の結果を怜玢しお元の問題の結果を取埗したす (泚: このタむプのアルゎリズムは分割統治ず呌ばれたす)。 このアルゎリズムが理解できなくおも、心配する必芁はありたせん。 初めお芋たずきは理解できたせんでした。 お圹に立おれば、このアルゎリズムは XNUMX 段階のアルゎリズムであるず考えられたす。

  • 分割フェヌズ。アレむがより小さなアレむに分割されたす。
  • 䞊べ替えフェヌズでは、小さな配列が (ナニオンを䜿甚しお) 結合されお、より倧きな配列が圢成されたす。

分割フェヌズ

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

分割段階では、アレむは 3 ぀のステップでナニタリアレむに分割されたす。 正匏なステップ数は log(N) です (N=8 なので、log(N) = 3)。

これをどうやっお知るのですか

私は倩才です 䞀蚀で蚀えば、数孊です。 各ステップで元の配列のサむズが 2 で陀算されるずいう考え方です。ステップ数は、元の配列を 2 ぀に分割できる回数です。 これは、察数 (底 XNUMX) の正確な定矩です。

遞別フェヌズ

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

䞊べ替えフェヌズでは、ナニタリ (単䞀芁玠) 配列から開始したす。 各ステップで耇数のマヌゞ操䜜を適甚するず、合蚈コストは N = 8 操䜜になりたす。

  • 最初のステヌゞでは、それぞれ 4 回の操䜜が必芁な 2 ぀のマヌゞがありたす。
  • 2 番目のステップでは、それぞれ 4 回の操䜜が必芁な XNUMX ぀のマヌゞがありたす。
  • 1 番目のステップでは、8 ぀の操䜜が必芁な XNUMX ぀のマヌゞがありたす。

log(N) ステップがあるので、 総コストN * log(N) 操䜜.

マヌゞ゜ヌトの利点

なぜこのアルゎリズムは非垞に匷力なのでしょうか?

なぜなら

  • これを倉曎しおメモリ フットプリントを削枛し、新しい配列を䜜成せずに入力配列を盎接倉曎するこずができたす。

泚: このタむプのアルゎリズムは in - 堎所 (远加メモリなしで゜ヌト)。

  • 倧幅なディスク I/O オヌバヌヘッドを発生させるこずなく、ディスク領域ず少量のメモリを同時に䜿甚するように倉曎できたす。 このアむデアは、珟圚凊理䞭の郚分のみをメモリにロヌドするこずです。 これは、100 メガバむトのメモリ バッファヌのみを䜿甚しおマルチギガバむトのテヌブルを゜ヌトする必芁がある堎合に重芁です。

泚: このタむプのアルゎリズムは 倖郚゜ヌト.

  • 耇数のプロセス/スレッド/サヌバヌで実行するように倉曎できたす。

たずえば、分散マヌゞ ゜ヌトは重芁なコンポヌネントの XNUMX ぀です。 Hadoopの (これはビッグデヌタの構造です)。

  • このアルゎリズムは鉛を金に倉えるこずができたす (本圓に!)。

この䞊べ替えアルゎリズムは (すべおではないにしおも) ほずんどのデヌタベヌスで䜿甚されおいたすが、これが唯䞀のデヌタベヌスではありたせん。 もっず詳しく知りたい堎合は、これを読むこずができたす 研究䜜業では、䞀般的なデヌタベヌス䞊べ替えアルゎリズムの長所ず短所に぀いお説明したす。

配列、ツリヌ、ハッシュテヌブル

時間蚈算量ず䞊べ替えの抂念を理解したずころで、3 ぀のデヌタ構造に぀いお説明する必芁がありたす。 これは重芁です。 最新のデヌタベヌスの基瀎ずなっおいたす。 コンセプトも玹介したす デヌタベヌスむンデックス.

アレむ

XNUMX 次元配列は最も単玔なデヌタ構造です。 テヌブルは配列ずしお考えるこずができたす。 䟋えば

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

この 2 次元配列は、行ず列を含むテヌブルです。

  • 各行ぱンティティを衚したす
  • 列には、゚ンティティを説明するプロパティが栌玍されたす。
  • 各列には、特定のタむプのデヌタ (敎数、文字列、日付など) が栌玍されたす。

これはデヌタの保存や芖芚化には䟿利ですが、特定の倀を怜玢する必芁がある堎合には適しおいたせん。

たずえば、英囜で働くすべおの男性を怜玢したい堎合は、各行を調べお、その行が英囜に属しおいるかどうかを刀断する必芁がありたす。 N回のトランザクションがかかりたすどこ N - 行数、これは悪くありたせんが、もっず速い方法はありたすか? 今床は朚に芪しんでみたしょう。

泚: 最新のデヌタベヌスのほずんどは、テヌブルを効率的に栌玍するための拡匵配列 (ヒヌプ構成テヌブルずむンデックス構成テヌブル) を提䟛したす。 ただし、列のグルヌプ内で特定の条件を迅速に芋぀けるずいう問題は倉わりたせん。

デヌタベヌスツリヌずむンデックス

二分探玢ツリヌは特別なプロパティを持぀二分朚であり、各ノヌドのキヌは次のずおりである必芁がありたす。

  • 巊偎のサブツリヌに栌玍されおいるすべおのキヌより倧きい
  • 右偎のサブツリヌに栌玍されおいるすべおのキヌよりも少ない

これが䜕を意味するかを芖芚的に芋おみたしょう

アむデア

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

このツリヌには N = 15 の芁玠がありたす。 208 を探しおいるずしたしょう:

  • キヌが 136 であるルヌトから開始したす。136<208 なので、ノヌド 136 の右偎のサブツリヌを調べたす。
  • 398>208 したがっお、ノヌド 398 の巊偎のサブツリヌを芋おいたす。
  • 250>208 したがっお、ノヌド 250 の巊偎のサブツリヌを芋おいたす。
  • 200<208 なので、ノヌド 200 の右偎のサブツリヌを芋おいたす。しかし、200 には右偎のサブツリヌがありたせん。 倀が存圚したせん (存圚する堎合、それは右偎のサブツリヌ 200 にあるため)。

では、40 人を探しおいるずしたしょう。

  • キヌが 136 のルヌトから開始したす。136 > 40 なので、ノヌド 136 の巊偎のサブツリヌを調べたす。
  • 80 > 40、したがっおノヌド 80 の巊偎のサブツリヌを芋おいたす。
  • 40= 40、 ノヌドが存圚したす。 ノヌド内の行 ID (図にはありたせん) を取埗し、テヌブル内で指定された行 ID を探したす。
  • 行 ID がわかれば、デヌタがテヌブル内のどこにあるかを正確に知るこずができるので、即座にデヌタを取埗できたす。

結局、䞡方の怜玢を行うず、ツリヌ内のレベル数が犠牲になりたす。 マヌゞ ゜ヌトに関する郚分を泚意深く読むず、log(N) レベルがあるこずがわかりたす。 それが刀明、 コストログの怜玢(N)、 悪くない

問題に戻りたしょう

しかし、これは非垞に抜象的なので、問題に戻りたしょう。 単玔な敎数の代わりに、前の衚の誰かの囜を衚す文字列を想像しおください。 テヌブルの「囜」フィヌルド (列 3) を含むツリヌがあるずしたす。

  • むギリスで働いおいる人を知りたい堎合
  • ツリヌを芋お、むギリスを衚すノヌドを取埗したす。
  • 「UKnode」内で英囜の劎働者蚘録の堎所がわかりたす。

配列を盎接䜿甚する堎合、この怜玢には N 操䜜ではなく log(N) 操䜜がかかりたす。 あなたが今提瀺したのは、 デヌタベヌスむンデックス.

キヌ (フィヌルド グルヌプ) を比范する関数があれば、任意のフィヌルド グルヌプ (文字列、数倀、2 行、数倀ず文字列、日付など) のむンデックス ツリヌを構築できたす。 キヌ間の順序 (デヌタベヌス内のすべおの基本タむプに圓おはたりたす)。

B+ツリヌむンデックス

このツリヌは特定の倀を取埗する堎合にはうたく機胜したすが、必芁な堎合には倧きな問題が発生したす。 XNUMX ぀の倀の間の耇数の芁玠を取埗する。 ツリヌ内の各ノヌドを調べお、これら XNUMX ぀の倀の間にあるかどうかを確認する必芁があるため (ツリヌの順序付けされた走査などで)、これには O(N) のコストがかかりたす。 さらに、この操䜜はツリヌ党䜓を読み取る必芁があるため、ディスク I/O に適しおいたせん。 効率的に実行する方法を芋぀ける必芁がある 範囲リク゚スト。 この問題を解決するために、最新のデヌタベヌスでは、B+Tree ず呌ばれる以前のツリヌの修正バヌゞョンが䜿甚されおいたす。 B+Tree ツリヌでは次のようになりたす。

  • 最䞋䜍のノヌド (葉) のみ 店舗情報 (関連テヌブル内の行の䜍眮)
  • 残りのノヌドはここにありたす ルヌティング甚 正しいノヌドに 怜玢䞭.

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

ご芧のずおり、ここにはさらに倚くのノヌドがありたす (XNUMX 回)。 実際、远加のノヌドである「決定ノヌド」があり、これは正しいノヌド (関連するテヌブル内の行の䜍眮を栌玍するノヌド) を芋぀けるのに圹立ちたす。 ただし、怜玢の耇雑さは䟝然ずしお O(log(N)) です (レベルが XNUMX ぀だけ増えおいたす)。 倧きな違いは、 䞋䜍レベルのノヌドは埌続ノヌドに接続されたす.

この B+Tree で、40 から 100 たでの倀を探しおいる堎合:

  • 前のツリヌの堎合ず同様に、40 (たたは 40 が存圚しない堎合は 40 に最も近い倀) を探すだけです。
  • 次に、盎接盞続人リンクを䜿甚しお 40 人に達するたで 100 人の盞続人を集めたす。

M 個の埌継者が芋぀かり、ツリヌに N 個のノヌドがあるずしたす。 特定のノヌドを芋぀けるには、前のツリヌず同様に log(N) のコストがかかりたす。 ただし、このノヌドを取埗するず、埌続者ぞの参照を持぀ M 個の操䜜で M 埌続者を取埗するこずになりたす。 この怜玢には M+log(N) のみのコストがかかりたす 前のツリヌの N 操䜜ず比范した操䜜。 さらに、ツリヌ党䜓 (M+log(N) ノヌドのみ) を読み取る必芁がないため、ディスク䜿甚量が少なくなりたす。 M が小さく (200 行など)、N が倧きい (1 行) 堎合、倧きな違いが生じたす。

しかし、ここで新たな問題が発生したすたたしおも。 デヌタベヌス (したがっお関連する B+Tree むンデックス) で行を远加たたは削陀するず、次のようになりたす。

  • B+ ツリヌ内のノヌド間の順序を維持する必芁がありたす。そうしないず、゜ヌトされおいないツリヌ内のノヌドを芋぀けるこずができなくなりたす。
  • B+Tree のレベルの最小数を維持する必芁がありたす。そうしないず、O(log(N)) の時間蚈算量が O(N) になりたす。

蚀い換えれば、B+Tree は自己秩序化され、バランスが取れおいる必芁がありたす。 幞いなこずに、これはスマヌトな削陀および挿入操䜜で可胜です。 ただし、これにはコストがかかりたす。B+ ツリヌでの挿入ず削陀には O(log(N)) のコストがかかりたす。 だからこそ、そう聞いたこずがある人もいるでしょう むンデックスを倚甚しすぎるのは埗策ではありたせん。 本圓に、 テヌブル内の行の高速な挿入/曎新/削陀が遅くなりたす。これは、デヌタベヌスがむンデックスごずにコストのかかる O(log(N)) 操䜜を䜿甚しおテヌブルのむンデックスを曎新する必芁があるためです。 さらに、むンデックスを远加するず、䜜業負荷が増加したす。 トランザクションマネヌゞャヌ (蚘事の最埌で説明したす)。

詳现に぀いおは、Wikipedia の蚘事を参照しおください。 B+朚。 デヌタベヌスに B+Tree を実装する䟋が必芁な堎合は、こちらをご芧ください。 この蚘事 О この蚘事 䞻芁な MySQL 開発者によるものです。 どちらも InnoDB (MySQL ゚ンゞン) がむンデックスを凊理する方法に焊点を圓おおいたす。

泚: 読者は、䜎レベルの最適化により、B+ ツリヌは完党にバランスが取れおいるはずだず教えおくれたした。

ハッシュ衚

最埌の重芁なデヌタ構造はハッシュ テヌブルです。 これは、倀をすばやく調べたい堎合に非垞に䟿利です。 さらに、ハッシュ テヌブルを理解するず、埌でハッシュ結合ず呌ばれる䞀般的なデヌタベヌス結合操䜜を理解するのに圹立ちたす ( ハッシュ結合。 このデヌタ構造は、デヌタベヌスによっお内郚的なもの (䟋: ロックテヌブル たたは バッファプヌル、これらの抂念の䞡方に぀いおは埌で説明したす)。

ハッシュ テヌブルは、キヌに基づいお芁玠を迅速に怜玢するデヌタ構造です。 ハッシュ テヌブルを構築するには、以䞋を定矩する必芁がありたす。

  • ключ あなたの芁玠のために
  • ハッシュ関数 鍵甚。 蚈算されたキヌ ハッシュにより、芁玠 (ず呌ばれる) の䜍眮がわかりたす。 セグメント ).
  • キヌを比范する関数。 正しいセグメントが芋぀かったら、この比范を䜿甚しおセグメント内で探しおいる芁玠を芋぀ける必芁がありたす。

簡単な䟋

わかりやすい䟋を芋おみたしょう。

リレヌショナル デヌタベヌスの仕組み (パヌト 1)

このハッシュ テヌブルには 10 個のセグメントがありたす。 私は怠け者なので 5 ぀のセグメントしかむメヌゞしたせんでしたが、あなたは賢いので、残りの 5 ぀は自分でむメヌゞしおもらいたしょう。 キヌの 10 を法ずするハッシュ関数を䜿甚したした。 蚀い換えれば、セグメントを芋぀けるために芁玠のキヌの最埌の桁のみを保存したす。

  • 最埌の桁が 0 の堎合、芁玠はセグメント 0 に分類されたす。
  • 最埌の桁が 1 の堎合、芁玠はセグメント 1 に分類されたす。
  • 最埌の桁が 2 の堎合、芁玠は領域 2 に分類されたす。
  • ...

私が䜿甚した比范関数は、XNUMX ぀の敎数間の単玔な等䟡性です。

芁玠 78 を取埗したいずしたす。

  • ハッシュ テヌブルは 78 のハッシュ コヌドを蚈算したす。぀たり 8 です。
  • ハッシュ テヌブルはセグメント 8 を調べ、最初に芋぀かった芁玠は 78 です。
  • 圌女はアむテム 78 をあなたに返したす
  • 怜玢にかかるコストはわずか 2 操䜜です (XNUMX ぀はハッシュ倀を蚈算するため、もう XNUMX ぀はセグメント内の芁玠を怜玢するためです)。

ここで、芁玠 59 を取埗したいずしたす。

  • ハッシュ テヌブルは 59 のハッシュ コヌドを蚈算したす。぀たり 9 です。
  • ハッシュ テヌブルはセグメント 9 を怜玢し、最初に芋぀かった芁玠は 99 です。99!=59 であるため、芁玠 99 は有効な芁玠ではありたせん。
  • 同じロゞックを䜿甚しお、9 番目の芁玠 (79)、29 番目の芁玠 (XNUMX)、...、最埌の芁玠 (XNUMX) が取埗されたす。
  • 芁玠が芋぀かりたせん。
  • 探玢には 7 回の操䜜が必芁です.

優れたハッシュ関数

ご芧のずおり、探しおいる䟡倀に応じお、コストは同じではありたせん。

ここで、キヌのハッシュ関数をモゞュロ 1 で倉曎した堎合 (぀たり、最埌の 000 桁を取埗した堎合)、セグメント 000 には芁玠がないため、6 回目の怜玢にかかる操䜜は 1 回だけです。 本圓の課題は、非垞に少数の芁玠を含むバケットを䜜成する適切なハッシュ関数を芋぀けるこずです。.

私の䟋では、適切なハッシュ関数を芋぀けるのは簡単です。 ただし、これは単玔な䟋であり、キヌが次の堎合、適切なハッシュ関数を芋぀けるのはより困難になりたす。

  • 文字列 (䟋: 姓)
  • 2 行 (䟋: 姓ず名)
  • 2 行ず日付 (䟋: 姓、名、生幎月日)
  • ...

適切なハッシュ関数を䜿甚するず、ハッシュ テヌブルの怜玢コストは O(1) になりたす。.

配列ずハッシュテヌブル

なぜ配列を䜿甚しないのでしょうか?

うヌん、良い質問ですね。

  • ハッシュ テヌブルは次のずおりです。 郚分的にメモリにロヌドされる、残りのセグメントはディスク䞊に残るこずができたす。
  • 配列では、メモリ内の連続した領域を䜿甚する必芁がありたす。 倧きなテヌブルをロヌドしおいる堎合 十分な連続スペヌスを芋぀けるのは非垞に困難です.
  • ハッシュ テヌブルの堎合、必芁なキヌ (囜や人の姓など) を遞択できたす。

詳现に぀いおは、次の蚘事をご芧ください。 Javaハッシュマップ、これはハッシュ テヌブルの効率的な実装です。 この蚘事で説明する抂念を理解するために Java を理解する必芁はありたせん。

出所 habr.com

コメントを远加したす