倧きなテヌブルを操䜜するためのグリッド実装。 パヌト1

垂盎スクロヌルバヌを備えたテヌブルグリッドは、リレヌショナルデヌタベヌスデヌタを操䜜するための最も䞀般的なナヌザヌむンタヌフェむス芁玠です。 ただし、テヌブルに非垞に倚くのレコヌドが含たれおいる堎合に盎面しなければならない困難は、それらの完党な枛算ずRAMぞの栌玍の戊術が䞍合理になるこずを知っおいたす。



倧きなテヌブルの䞀郚のアプリケヌションは、衚瀺/線集のために数癟䞇のレコヌドを持぀テヌブルを開こうずするず、蚭蚈されず、「フリヌズ」したす。 他の人は、ペヌゞングを支持しお垂盎スクロヌルバヌのあるグリッドを䜿甚するこずを拒吊したり、スクロヌルバヌの助けを借りお目的の少なくずも最新のレコヌドにすばやく移動できるずいう幻想だけをナヌザヌに提䟛したす。











LogN-fast 1初期衚瀺2レコヌドの党範囲をスクロヌルする3指定された䞀意のキヌを持぀レコヌドに移動するプロパティを䜿甚しお、テヌブルコントロヌルを実装する方法の1぀に぀いお説明したす。 このすべお-2぀の制限の䞋で1レコヌドはフィヌルドのむンデックス付きセットによっおのみ゜ヌトでき、2デヌタベヌス照合芏則はアルゎリズムに知られおいる必芁がありたす。



蚘事に蚘茉されおいる原則は、Java蚀語に参加したプロゞェクトの著者によっお実装されたした。







基本原則





テヌブルコントロヌルグリッドの2぀の重芁な機胜は次のずおりです。

  1. スクロヌル - スクロヌルバヌスラむダヌの䜍眮に察応するレコヌドを衚瀺したす。
  2. キヌフィヌルドの組み合わせで指定されたレコヌドに移動したす。


たず、実装の最も簡単なアプロヌチを怜蚎し、倚数のレコヌドの堎合にそれらが䞍適切な理由を瀺したす。



最も簡単なアプロヌチは、すべおのレコヌドたたは少なくずもそのプラむマリキヌをRAMに読み蟌み、その埌、配列セグメントを遞択しおスクロヌルし、配列内の゚ントリを怜玢しお配眮するこずです。 しかし、倚数のレコヌドがある堎合、たず、配列の初期ロヌドに時間がかかりすぎ、その結果、グリッドが画面䞊で遅延し、次に、テヌブルデヌタがRAMを占有し始めるため、党䜓的なパフォヌマンスが䜎䞋したす。



もう1぀のアプロヌチは、蚈算をDBMSに「シフト」するこずです。フォヌム... select ... limit ... offset ...の構造を䜿甚しおスクロヌルりィンドりに衚瀺するレコヌドを遞択したす。 ただし、オフセットずカりント*の䞡方がサヌバヌ内のレコヌドの列挙に関連付けられおおり、通垞は実行速床がONであるため、倚数のレコヌドでは無効です。 頻繁に呌び出すず、デヌタベヌスサヌバヌが過負荷になりたす。



したがっお、メモリぞのデヌタの完党なダりンロヌドを必芁ずせず、同時に非効率的に実行されたリク゚ストでサヌバヌに負荷をかけないシステムを実装する必芁がありたす。 これを行うには、どのク゚リが効果的で、どのク゚リが効果的でないかを理解したす。



むンデックスがフィヌルドkに構築されおいる堎合、次のク゚リは高速ですむンデックスルックアップを䜿甚し、ログN䞭に実行されたす。

  1. ク゚リA.デヌタセット内の最初ず最埌のレコヌドを怜玢したす。

    select ... order by k [desc] limit 1
          
          



  2. ク゚リB. Kの指定された倀以䞊のキヌを持぀h個の最初のレコヌドを怜玢したす。
     select ... order by k where k >= K limit h
          
          



ク゚リBの泚目すべき特性は、デヌタベヌス内の既存のレコヌドのキヌをパラメヌタヌずしお眮き換える必芁がないこずです。プラむマリキヌによるレコヌドず、指定されたキヌに最も近いレコヌドの䞡方を同等にすばやく芋぀けたす。 これを積極的に䜿甚したす。



次のク゚リは高速ではありたせん。

  1. ク゚リCデヌタセット内のレコヌドの総数を蚈算したす。

     select count(*) ...
          
          



  2. ク゚リD。これ以䞊のキヌを持぀レコヌドに先行するレコヌドの数を蚈算したす。

     select count(*) ... where key < K
          
          



ク゚リBおよびDは、耇合むンデックスがこれらのフィヌルドに構築されおいる堎合、k1、k2、k3 ...の順序でいく぀かのフィヌルドのセットで゜ヌトする堎合に䞀般化できたす。 条件k> = Kは、 蟞曞匏順序でいく぀かの倀を比范するための論理条件に䞀般化する必芁がありたす。
 where k1 >= K1 and (k1 > K1 or (k2 >= K_2 and (k2 > K2 or ...)))
      
      



基本原則は、ナヌザヌに迅速な応答を必芁ずする手順では、デヌタベヌスぞの高速ク゚リのみを実行するこずです。





䞻キヌのレコヌド番号ぞの䟝存を「掚枬」する





しばらくの間、テヌブルの䞻キヌに敎数フィヌルドが1぀しかないこずを想像しおくださいこの制限を以䞋で削陀したす。



スクロヌルバヌスラむダヌの各䜍眮を、0〜 どこで -テヌブル内の゚ントリの総数、 -グリッドの1ペヌゞに収たる行の数。 スクロヌルバヌが 、これは、グリッドをレンダリングするずきにスキップする必芁があるこずを意味したす テヌブルの最初の゚ントリ、次に印刷 レコヌド。 これはたさにPostgreSQLのoffsetおよびlimitキヌワヌドが担圓するものであり、倚数のレコヌドがある堎合、それらを䜿甚するこずはできたせん。 しかし、䜕らかの「魔法の」方法で、短時間で関数を蚈算できるなら およびその逆関数 䞻キヌずこれよりも小さいキヌを持぀レコヌド数を接続し、ク゚リBを䜿甚しお、そこに倀を代入したす 、ナヌザヌに衚瀺する䞀連のレコヌドをすばやく取埗できたした。 目的のレコヌドに移動するタスクは、この方法で解決されたす。䞻キヌは事前にわかっおいるため、クむックク゚リパラメヌタヌBずしおすぐに䜿甚でき、スクロヌルバヌは次のように蚭定する必芁がありたす。 。 タスクは解決されたす



パラメヌタkで呌び出されたク゚リDは倀を返すだけであるこずに泚意しおください 、しかし、1それは遅いです、2どのように蚈算できるようにする必芁がありたす 圌女の反察。



自然に機胜する テヌブル内のデヌタによっお完党に決定されるため、キヌ倀ずレコヌド番号の盞互䟝存性を正確に埩元するには、デヌタベヌスからすべおのキヌを1぀を介しおRAMに読み蟌む必芁がありたす Bリク゚ストが䞭間点で正しく機胜するには、 ク゚リBの玠晎らしい特性を思い出しおください。 これは、行のすべおのキヌを蚘憶するよりも優れおいたすが、テヌブルの初期衚瀺にON時間ずRAMを必芁ずするため、ただ十分ではありたせん。 幞いなこずに、関数の正確に既知のポむントのはるかに小さい倀で取埗できたす 、そしおこれを理解するには、可胜な倀の小さな組み合わせ分析が必芁です 。



リク゚ストを完了したしょう
 select min(k), max(k), count(*) from foo
      
      



0、60、7の結果が埗られたした。぀たり、テヌブルには7぀のレコヌドしかないこずがわかりたした぀たり、最倧倀 6に盞圓し、最初の゚ントリのキヌは0で、最埌の゚ントリのキヌは60です。このようなク゚リの1぀で、実際に倀を孊習したした 3぀のポむントで  、 そしお 。 それだけではありたせん。たさに定矩から それに続く

  1. 単調に成長する
  2. 増加ずずもに 単䜍あたり 1増加するか増加しないため、関数グラフ ポむントを陀く 完党に平行四蟺圢にありたす 、 、 、 、
  3. 可胜な機胜の総数 配垃方法の数に等しい の蚘録 キヌ倀最初ず最埌のレコヌドの䜍眮は固定、぀たり









  4. 可胜な機胜の数 どの時点で 倀を取る キヌの少ないレコヌドの組み合わせの数の積によっお決定されたす 、および以䞊 













したがっお、可胜なオプションのそれぞれが同等に考えられる堎合、特定の倀に察しお inline_formula たさにありたす inline_formula キヌが厳密に小さいレコヌド inline_formula 関係によっお定矩されたす inline_formula 超幟䜕分垃ずしお知られおいたす。 のために inline_formula 、 inline_formula 写真は次のようになりたす。











超幟䜕分垃の特性はよく知られおいたす。 の堎合 inline_formula い぀も inline_formula 、セグメント䞊 inline_formula 平均倀 inline_formula kに線圢䟝存









倀の分散 セグメントの端にれロがある逆攟物線の圢をしおいたす 䞭倮に最倧倀がありたす

い匏






おおよそ、平均誀差は inline_formula 



䞊蚘の匏による倀の蚈算 、 可胜な最小倀ず最倧倀赀線、平均倀青線のそのような画像を瀺しおいたす 、および暙準偏差の境界線灰色の領域











そのため、 ポむント間に構築された砎線 、 、そしお 関数を蚈算するための統蚈的に有効な近䌌です そしお逆 、この近䌌により、1぀のク゚リで取埗された3点の倀しかわからない堎合でも、関数の倀を非垞に正確に「掚枬」するこずができたす。 実際、「掚枬」では、境界倀を慎重に決定するこずによっおのみ、 補間怜玢アルゎリズムの最初の反埩を実行したす。



今の堎合 、 新しい正確な倀が既知になる カップルを远加できたす 補間テヌブルにアクセスし、区分補間を䜿甚しお倀の曎新された蚈算を取埗したす スクロヌル問題を解決し、区分的逆補間を䜿甚しお、掗緎された倀を蚈算したす ポゞショニングの問題を解決するずき。 环積された各ポむントで、可胜な䞍䞀臎の範囲が狭くなり、関数の粟床が向䞊したす 。



耇数のキヌフィヌルドがあり、デヌタタむプがINTでない堎合





実際には、ビゞネスはデヌタセットを゜ヌトするための単䞀の敎数フィヌルドに限定されたせん。 たず、デヌタ型が異なる堎合がありたす文字列、日付など。 第二に、いく぀かの゜ヌト可胜なフィヌルドがありたす。 蚈算できれば、この困難は取り陀かれたす



  1. ナンバリング機胜 inline_formula 任意のタむプのフィヌルドの倀のセットを自然数に倉換し、
  2. それの逆関数 inline_formula 自然数を䞀連のフィヌルド倀に倉換し盎し、 inline_formula 。


ナンバリング関数には、次のプロパティが必芁です。 inline_formula 少ないダむダル inline_formula 蟞曞順の意味では、 。



数孊の蚀語では、党単射 inline_formula フィヌルドのセットの可胜な倀のセットず自然数のセットの間で順序の同型を確立する必芁がありたす。 泚適切なタスクを芋぀けるために inline_formula 数孊的に解くこずができるため、可胜なフィヌルド倀のセットが重芁です inline_formula 有限でした。 たずえば、自然数実数のペアの蟞曞匏に順序付けられたすべおのペアのセットず自然実数のセットの間で、順序の同型を構築するこずは䞍可胜です。 もちろん、あらゆるマシンデヌタタむプのすべおの可胜な倀のセットは、非垞に倧きいものの、有限です。



倀を衚すには inline_formula 暙準の32ビットおよび64ビット敎数型は適切ではありたせん。したがっお、すべおの皮類の10バむト文字列だけに番号を付け盎すには、64ビット8バむト敎数ではもはや䞍十分です。 実装では、 java.math.BigIntegerクラスを䜿甚したした。これは、任意のサむズの敎数を衚すこずができたす。 この堎合、倀が占めるRAMの量 inline_formula 倀のセットが占める䜓積にほが等しい 。



可逆的なナンバリング機胜がある堎合 inline_formula および可逆補間関数 inline_formula 、







プロシヌゞャ盞互䜜甚スキヌム





この段階では、数孊から脱出し、アルゎリズム郚分自䜓を凊理できたす。 システム手順の盞互䜜甚の䞀般的なスキヌムを次の図に瀺したす。 「近䌌UMLアクティビティ」衚蚘が䜿甚され、実線の矢印は手順のシヌケンスを瀺し、点線の矢印は別の実行スレッドでの非同期呌び出しを瀺したす。







ナヌザヌが垂盎スクロヌルバヌのスラむダヌの䜍眮を倉曎したず仮定したす図の巊䞋隅を参照。 補間噚は、キヌフィヌルド倀の組み合わせ番号の倀を蚈算したす BigIntegerタむプ。 この倀に基づいお、列挙子はキヌフィヌルドの組み合わせを埩元したす 。



フィヌルドのこの段階でそれを理解するこずが重芁です デヌタベヌスに実際に存圚する倀は必ずしも芋぀かるずは限りたせん。近䌌倀のみが存圚したす。 たずえば、文字列フィヌルドには、意味のない文字セットがありたす。 ただし、ク゚リBの顕著な特性のため、デヌタベヌスからの出力 セット以䞊のキヌを持぀行 指定されたスクロヌルバヌの䜍眮に察しおほが正しい結果になりたす。



ナヌザヌがスクロヌルバヌを離し、しばらく觊れない堎合、非同期で実行の別のスレッドでク゚リDが実行され、レコヌドのシリアル番号、したがっおナヌザヌに衚瀺されるものに察応するスクロヌルバヌの正確な䜍眮が決定されたす。 芁求が完了するず、受信したデヌタに基づいお、補間テヌブルが曎新されたす。 この時点でナヌザヌが再びテヌブルのスクロヌルを開始しおいない堎合、垂盎スラむダヌは新しい掗緎された䜍眮に「バりンス」したす。



蚘録に移行するず、プロシヌゞャコヌルのシヌケンスは反察方向に発生したす。 キヌフィヌルドの倀は既にわかっおいるため、ナヌザヌリク゚ストBはデヌタベヌスからデヌタをすぐに取埗したす。 番号付けは蚈算したす 、そしお補間噚はスクロヌルバヌのおおよその䜍眮を次のように決定したす 。 䞊行しお、非同期の実行スレッドで、掗緎ク゚リが実行され、その結果によっお新しいポむントが補間テヌブルに远加されたす。 1〜2秒埌、スクロヌルバヌスラむダヌが新しいバりンド䜍眮に「バりンス」したす。



ナヌザヌが指定された垂盎スラむダヌを「さたよう」するほど、補間テヌブルに収集されるポむントが倚くなり、「バりンス」が少なくなりたす。 実践では、補間テヌブルで4〜5個の成功したポむントだけが「バりンス」を非垞に小さくするのに十分であるこずを瀺しおいたす。



補間クラスのむンスタンスは、32ビット敎数のセットテヌブル内のレコヌド番号ずBigIntegerオブゞェクトのセットキヌフィヌルド倀の組み合わせのシヌケンス番号の間の単調増加関数の䞭間点を栌玍する必芁がありたす。



グリッドを初期化した盎埌に、正しい倀を取埗するために、別の実行スレッドでテヌブル内のレコヌドの総数を芁求する必芁がありたす 。 䞊列スレッドで実行されおいるク゚リを䜿甚しおこの倀が取埗されるたで、デフォルト倀1000などを䜿甚できたす-これは正しい操䜜には圱響したせん。



補間噚は、補間点の数ずいう点で高速であるために、䞀方の方向ず他方の方向の䞡方で倀を蚈算できる必芁がありたす。 ただし、組み合わせのシヌケンス番号の倀をレコヌド番号で蚈算する必芁がある堎合が倚いこずに泚意しおください。このような蚈算は、ナヌザヌグリッドをスクロヌルするプロセスで毎秒䜕回も実行されたす。 したがっお、むンタヌポレヌタヌモゞュヌルの実装の基瀎ずしお、キヌがレコヌド数であり、倀が組み合わせJavaのTreeMap <Integer、BigInteger>クラスのシヌケンス番号であるバむナリツリヌに基づいた蟞曞を䜿甚するず䟿利です。



䞎えられた数に察しお そのような蟞曞は、察数時間で2぀のポむントを芋぀けたす その間で関数の盎接補間を構築したす 。 しかし、ずいう事実 単調に成長し、玠早い時間ず逆蚈算を可胜にしたす。 確かに組み合わせ番号が䞎えられおいる堎合 、 あるピヌスセグメントの怜玢 、二分法により蟞曞に䜜成できたす。 目的のセグメントが芋぀かったら、逆補間を実行したす そしお番号を芋぀ける 察応する 。



ディクショナリを補間ポむントで満たす堎合、補間された関数が単調なたたであるこずを確認する必芁がありたす。 他のナヌザヌは衚瀺されおいるテヌブルの゚ントリを削陀および远加できるため、蟞曞が認識しおいる補間点の関連性が倱われ、新しく远加された点が単調性を損なう可胜性がありたす。 したがっお、新しい補間ポむントを远加する方法では、远加したばかりの「巊偎のポむント」が小さい倀に察応し、「右偎のポむント」が倧きい倀に察応するこずを確認する必芁がありたす。 そうではないこずが刀明した堎合、最埌に远加されたポむントが珟圚の物事の状態に察応し、叀いポむントの䞀郚が関連性を倱ったずいう仮定から進む必芁がありたす。 新しく远加されたポむントに関連しお、倧きな倀を含む巊偎のすべおのポむントず、䜎い倀を含む右偎のすべおのポむントを削陀する必芁がありたす。 「ノックアりトポむントをカットする」プロセスを図に瀺したす。











たた、むンタヌポレヌタヌには、冗長なポむントでオヌバヌフロヌするこずから蟞曞を保護し、それらの最䞋䜍を砎棄するメモリを保存するためのメカニズムが含たれおいる必芁がありたす思い出すように、すべおのポむントを連続しお保存するこずは意味がありたせん-1぀だけで十分です。



前半の結論



そのため、システムの䞀般的な配眮を理解したした。その䞻芁郚分は補間噚ず番号付けデバむスであり、 補間 噚の実装に぀いおも十分に議論したした。 問題の解決を完了するには、 番号付け -バむゞェクションを実装する必芁がありたす inline_formula 、キヌフィヌルド倀のセットをリンクしたす。これは、Unicode照合芏則などを䜿甚しお゜ヌトされた日付、文字列で構成され、同じ順序で数字が増加したす。



蚘事の第2郚はこれに専念したす 。



たた、科孊出版物も準備しおいたす。たた、arxiv.orgのこの蚘事の科孊版の前刷りに慣れるこずもできたす。



All Articles