プログラミング蚀語の基瀎ずなるメモリモデル

プログラミングで䜿甚されるメモリモデルの怜蚎に関する蚘事の翻蚳に泚目しおください。

珟圚、6぀の䞻芁なメモリモデルがプログラミングを支配しおいたす Intel 8086メモリモデルず混同しないでください。 それらの3぀は、1950幎代の歎史的に最も重芁な3぀のプログラミング蚀語であるCOBOL、LISP、およびFORTRANに由来し、残りは、磁気テヌプ、Unixスタむルの階局ファむルシステム、リレヌショナルデヌタベヌスの3぀の歎史的に重芁なストレヌゞシステムに関連付けられおいたす。

これらのモデルは、構文や型システムよりもはるかに深いレベルで、プログラミング蚀語ができるこずたたはできないこずを決定したす。 これらのモデルを詳しく芋お、考えられる代替案ずそれらが興味深い理由を説明したしょう。

はじめに


珟代の各プログラミング環境は、ある皋床、6぀のメモリモデルすべおを䜿甚したす。これが、システムが非垞に耇雑で理解しにくい理由の1぀です。

ここで、これらの各メモリモデルを分析したす。

  1. ゚ンティティの属性を衚したす
  2. シリアル化ず察話し、
  3. プログラムのモゞュヌル性を実装および維持し、特定の偎面ぞのアクセスを制限し、ロヌカルたたはプラむベヌトにしたす。

プロロヌグアトミック倉数のみを持぀プログラム


単玔なプログラミング蚀語から始めたしょう。クロヌゞャヌがなく、ブヌル倀ず有限粟床の数以倖のデヌタ型が含たれおいないため、デヌタを構造化する可胜性がありたせん。 以䞋に、通垞のセマンティクスず通垞の操䜜の優先床を䜿甚したBNFの説明を瀺したす。

program ::= def* def ::= "def" name "(" args ")" block args ::= "" | name "," args block ::= "{" statement* "}" statement ::= "return" exp ";" | name ":=" exp ";" | exp ";" | nest nest ::= "if" exp block | "if" exp block "else" block | "while" exp block exp ::= name | num | exp op exp | exp "(" exps ")" | "(" exp ")" | unop exp exps ::= "" | exp "," exps unop ::= "!" | "-" | "~" op ::= logical | comparison | "+" | "*" | "-" | "/" | "%" logical ::= "||" | "&&" | "&" | "|" | "^" | "<<" | ">>" comparison ::= "==" | "<" | ">" | "<=" | ">=" | "!=" 

この蚀語で枩床を華氏から摂氏に倉換する䟋

 def f2c(f) { return (f — 32) * 5 / 9; } def main() { say(f2c(-40)); say(f2c(32)); say(f2c(98.6)); say(f2c(212)); } 

プログラミング蚀語では再垰が犁止されおおり、倀による呌び出しを行う貪欲な熱心な蚈算戊略が䜿甚されおいるこずに同意したしょう。 たた、すべおの倉数が暗黙的にロヌカルであり、サブプログラムを呌び出すずきにれロで初期化されるこずに同意したす。 したがっお、サブルヌチンには副䜜甚がありたせん。 この圢匏では、プログラミング蚀語は有限状態マシンのプログラミングにのみ適甚できたす。 レゞスタを備えた実際のプロセッサ甚にこのようなプログラムをコンパむルするず、プログラムテキスト内の各倉数に1぀のレゞスタを割り圓おるこずができたす。 各ルヌチンには、戻りアドレス甚のレゞスタを割り圓おるこずもできたす。 たた、呜什カりンタには別のレゞスタが必芁です。 ギガバむトのRAMを搭茉したマシンでこの蚀語のプログラムを実行しおも利点はありたせん。 圌女は最初に持っおいた以䞊の倉数を䜿甚するこずはできたせんでした。

これにより、このような蚀語が圹に立たなくなりたす。 限られたスペヌスで行える倚くの䟿利な蚈算がありたす。 しかし、これでは、そのような蚈算であっおも、その抜象的なパワヌを完党に䜿甚するこずは実際には蚱可されたせん。

远加のメモリにアクセスするには、指定されたアドレスに察しお1バむトを読み曞きするpeekおよびpoke関数を䜿甚できたす。 したがっお、メモリを本圓に効率的に䜿甚できたす。

 def strcpy(d, s, n) { while n > 0 { poke(d + n, peek(s + n)); n := n — 1; } } 

ただし、倚くのプログラミング蚀語では、peekおよびpokeも提䟛されおいたせん。 代わりに、それらは犁欲的な同皮のバむト配列の䞊にある皮の構造を提䟛したす。

たずえば、ステヌトマシン、ネストされたレコヌド、配列、およびナニオンをプログラミングする堎合でも、すでに倧きなメリットがありたす。

ネストされたレコヌドずCOBOLメモリモデル損益蚈算曞ずしおのメモリ


COBOLでは、デヌタオブゞェクトは分割䞍可胜なものです。


ここでは、この蚀語が提䟛するものの理解を簡玠化するために、COBOLの甚語ず分類法から倧幅に逞脱しおいたす。


このようなメモリモデルでは、耇数の類䌌した゚ンティティがある堎合、各゚ンティティは情報を栌玍するために蚭蚈された同じタむプのレコヌドサむズずサブフィヌルドの䞡方を持ちたす。 したがっお、この゚ンティティに関するすべおの情報はメモリ内に順番に配眮されたす。 これらの関連デヌタをディスク、テヌプ、パンチカヌド、たたはその他のストレヌゞメディアに非垞に簡単にダりンロヌドしお保存できたす。 これらのレコヌドのいく぀かが同時にメモリ内にある堎合、それらを配列に配眮できたす。

゚ンティティの属性は2バむトで定矩されたす。2バむトは、この゚ンティティのデヌタを栌玍するレコヌドのベヌスアドレスを基準ずした、この属性の開始ず終了のオフセットです。 たずえば、Accountオブゞェクトには10​​〜35バむトの所有者フィヌルドがあり、その䞭には18〜26バむトのアカりント所有者のPatron名が栌玍されたす。

このアプロヌチには、興味深い点がいく぀かありたす。

ポむンタはたったくありたせん。 これは、動的なメモリ割り圓おを行う方法がなく、nullポむンタを逆参照できず、ダングリングポむンタを䜿甚しおメモリ領域を䞊曞きしないこずを意味したすただし、2぀の倉数がREDEFINESずしお宣蚀されおいる堎合は、もちろん互いに䞊曞きしお回避できたす タグ付きのナニオン 、メモリ䞍足、オヌバヌラップ、ポむンタヌでのメモリの浪費は、この問題に圹立ちたせん。

䞀方、これはたた、プログラム内のすべおのデヌタ構造には厳しい制限があり、異なる時間に異なるものに同じメモリを䜿甚する唯䞀の方法は、それらを同時に䜿甚するリスクがあるこずを意味したす。

ネストされた゚ントリは非垞に経枈的で、メモリが節玄されたす。 珟圚䜜業しおいる゚ンティティのデヌタのみに留意する必芁がありたす。 これは、キロバむトのメモリを搭茉したマシンでメガバむトのデヌタを正垞に凊理できるこずを意味したす。これは、COBOLプログラマヌが1950幎代に行ったこずでした。

各デヌタフィヌルド、サブフィヌルドなどには1぀の䞀意の芪があり最䞊䜍レベルを陀く、すぐにすべおの子デヌタが含たれたす。

このメモリモデルでは、プログラムの䞀郚に独自のメモリたずえば、スタックフレヌムや静的なプラむベヌト倉数がある堎合、この独自のメモリにデヌタを保存するこずで、䞀郚の゚ンティティをプラむベヌトにするこずができたす。 これは、ロヌカルの䞀時倉数を䜜成する必芁があり、それがプログラムの残りの郚分に圱響しないこずを確認する堎合に䟿利です。 ただし、このようなメモリモデルでは、プログラムのどの郚分でも属性をプラむベヌトにするこずはできたせん。

ALGOLおよびALGOL-58ずALGOL-60は、配列に加えお、デヌタ構造化メカニズムをメむンずしおCOBOLからレコヌドを借甚したした。 そしお、ほずんどすべおの他のプログラミング蚀語が䜕らかの圢でそれを継承したのは、アルゎルからでした。

C蚀語には、デヌタを構造化するためのほがすべおのツヌルセットプリミティブ型char、intなど、構造䜓、共甚䜓、配列がありたす。 ただし、Cには、匕数を受け入れるだけでなく、再垰的なポむンタヌずルヌチンもあり、スタックを割り圓おるようなものが必芁です。 COBOLモデルに察するこれらの拡匵機胜はどちらもLISPから提䟛されたした。

オブゞェクトグラフずLISPメモリモデルマヌク付き指向グラフずしおのメモリ


LISP珟圚はLispであり、1959幎にはLISPでしたは、COBOLずほずんど倉わらないでしょう。 ポむンタがあるだけでなく、LISPには他にほずんど䜕もありたせん。 LISPでデヌタを構造化するための唯䞀のメカニズムはconsず呌ばれるもので、2぀のポむンタヌで構成されたす。1぀は「car」、もう1぀は「cdr」です。 任意の倉数の倀はポむンタヌです。 短所ぞのポむンタ、シンボルぞのポむンタ、数倀ぞのポむンタ、たたはサブプログラムぞのポむンタの堎合もありたすが、ポむンタです。



さらに、匕数付きの再垰ルヌチンがあり、これずテヌルテヌル再垰最適化のおかげで、倉数の倀を倉曎するこずなく䜕かをするプログラムを曞くこずができたす。

任意のオブゞェクトは、任意の数のポむンタヌによっお参照でき、そのポむンタヌを䜿甚しおオブゞェクトを倉曎できたす。 したがっお、オブゞェクトには䞀意の芪はありたせん。

このモデルは、自然蚀語の凊理、プログラムの解釈ずコンパむル、 培底的な怜玢、およびシンボリック蚈算のためのプログラムをかなり簡単に䜜成できるずいう意味で、非垞に柔軟性がありたす 。 たた、デヌタ構造 赀黒朚など を䞀床䜜成しお、それをさたざたなタむプのオブゞェクトに簡単に適甚するこずもできたす。 察照的に、CなどのCOBOL掟生蚀語には、この皮の䞀般化に倧きな困難がありたす。その結果、プログラマヌは、新しいデヌタ型に同じよく知られおいるデヌタ構造ずアルゎリズムを実装するために、膚倧な量の反埩コヌドを䜕床も曞く必芁がありたす。

ただし、同時に、このモデルはメモリの制限にうたく察応できず、゚ラヌが発生しやすく、効果的な実装には倚くの工倫が必芁です。 各オブゞェクトはポむンタヌによっおのみ識別されるため、各オブゞェクトぱむリアスを持぀こずができたす。 各倉数はNULLポむンタヌにするこずができたす。 ポむンタヌは䜕でも指すこずができるため、型゚ラヌ1぀の型のオブゞェクトぞのポむンタヌが他の型を指すず予想される倉数に栌玍されおいる堎合はいたるずころにあり、オブゞェクトグラフ蚀語は埓来、チェックを䜿甚しおデバッグ時間を短瞮したす実行時にタむプしたす。

このオブゞェクトグラフメモリモデルでは、同じタむプのオブゞェクトが耇数ある堎合、それぞれがポむンタヌによっお識別され、オブゞェクトの特定の属性を芋぀けるには、このポむンタヌから開始しおオブゞェクトのグラフをナビゲヌトする必芁がありたす。 たずえば、Accountオブゞェクトがある堎合、連想リストの圢匏で衚瀺できたす。 次に、その所有者他のアカりントオブゞェクトず組み合わせお䜿甚​​できるオブゞェクトを芋぀けるには、ACCOUNT-HOLDERになる車の短所を芋぀けおそのcdrを取埗するたでリストを調べたす。 次に、アカりント所有者のミドルネヌムを芋぀けるために、おそらくアカりント所有者の属性のベクトルを探しおいる堎合、察応する名前ぞのポむンタヌを取埗したす。これは、行が存圚しない叀いLispのように、文字列たたは蚘号のいずれかです。 ミドルネヌムの曎新には、この所有者オブゞェクトが他のアカりントオブゞェクトで䜿甚されおいるかどうか、および、他のアカりント。ミドルネヌムも曎新されたす。

これらの蚀語では、ガベヌゞコレクションがほが必芁です。 McCarthyがLispを䜜成した1959幎から、LiebermanずHewittが䞖代を䜿甚しおガベヌゞを収集するずいうアむデアを思い぀いた1980幎たで、このメモリモデルを䜿甚するプログラムは䜜業の3分の1から半分をガベヌゞコレクションに費やしおいたした。 䞀郚のコンピュヌタヌは、ガベヌゞコレクタヌを別のプロセッサヌで実行できるように、耇数のプロセッサヌで特別に蚭蚈されおいたす。

オブゞェクトグラフィカル蚀語は、既存のオブゞェクトを倉曎するよりも新しいオブゞェクトを䜜成するこずを奜むためだけでなく、通垞倚くのポむンタヌを持っおいるため、ガベヌゞコレクタヌに高い芁求を行いたした。 CやGolangなどのCOBOL掟生蚀語では、ガベヌゞコレクタヌで実行されるメモリ操䜜が少なくなるため、ガベヌゞコレクタヌが動䜜しやすくなりたす。 これらの蚀語は、倉曎されたバヌゞョンのメモリを再割り圓おするのではなく、オブゞェクトを倉曎する傟向がありたす。 そしおプログラマヌは、原則ずしお、可胜な堎合はネストされたレコヌドを䜿甚し、ポむンタヌに関連付けないようにしたす。そのため、ポむンタヌは、ポリモヌフィズム、空のポむンタヌの蚱容性ポリモヌフィズムの特殊なケヌスず芋なすこずができるが望たしい堎合にのみ芋぀かりたす。

オブゞェクトグラフのシリアル化は、埪環参照を含めるこずができるため、たたシリアル化する必芁のない郚分ぞのリンクが含たれる可胜性があるため、少し耇雑になりたす。䞡方のケヌスを特定のケヌスず芋なす必芁がありたす。 たずえば、䞀郚のシステムでは、クラスのむンスタンスにそのクラスぞのリンクが含たれ、クラスにはすべおのメ゜ッドの珟圚のバヌゞョンだけでなく、芪クラスぞのリンクも含たれたす。 そしお、おそらくオブゞェクトのすべおのシリアル化でクラスのバむトコヌド党䜓をシリアル化する必芁はありたせん。 さらに、以前にリンクを共有しおいた2぀のオブゞェクト同じアカりント所有者の2぀のアカりントを逆シリアル化する堎合、おそらくそれらを共有し続ける必芁がありたす。 䞀般に、これに関する特定のポリシヌは、デヌタをシリアル化する目的によっお異なる堎合がありたす。

ネストされた゚ントリを持぀メモリモデルのように、オブゞェクトグラフモデルを䜿甚するず、特定の゚ンティティのすべおの属性をプログラムの特定の郚分にロヌカルにするこずができたす。プログラムの残りの郚分のデヌタ構造ぞの参照を䞎えるこずはできたせんが、特定の属性をプラむベヌトにするこずはできたせんすべおの゚ンティティ。 ただし、ネストされた゚ントリを持぀メモリモデルずは異なり、オブゞェクトグラフモデルは、ノヌドのメモリサむズぞの䟝存性を枛らしたす。これにより、倚くの深刻な問題にもかかわらず、オブゞェクト指向の継承ぞの扉が開かれ、属性をプラむベヌトにするこずができたす。

このモデルは、珟圚最も䞀般的なプログラミング蚀語で䜿甚されおいたす。 珟圚のLispだけでなく、Haskell、ML、Python、Ruby、PHP5、Lua、JavaScript、Erlang、Smalltalkもありたす。 それらはすべお、メモリ内に存圚するオブゞェクトのタむプのセットを単玔なペアを超えお拡匵したした。 通垞、ポむンタの配列ず文字列のハッシュテヌブル、たたは他のポむンタぞのポむンタが含たれたす。 それらの䞀郚には、タグ付き共甚䜓ず䞍倉゚ントリも含たれたす。 特に、ハッシュテヌブルは、ほずんどの堎合、これらのオブゞェクトを䜿甚する他のコヌドに圱響を䞎えずに、既存のオブゞェクトに新しいプロパティを远加する䞀皮の方法を提䟛したす。



䞀般に、これらの蚀語では、グラフの゚ッゞを指す方向にのみ远跡でき、゚ッゞのラベルは゜ヌスノヌド内で䞀意である必芁がありたすconsには1台の車のみがあり、2台ではなく10台。目的地。 Ted NelsonのZigZagデヌタ構造は、送信元ず送信先の䞡方で䞀意である必芁がある状況の研究です。 UnQLは、ある意味、䞀意性を完党に排陀する研究です。


JavaおよびCは、このメモリモデルのわずかに倉曎されたバヌゞョンを䜿甚したす。たずえば、Javaには、ポむンタヌではない「プリミティブ型」などがありたす。

䞊列配列ずFORTRANメモリモデル配列のグルヌプずしおのメモリ


Fortranは、コンピュヌタヌの最も初期のアプリケヌションの1぀である物理珟象いわゆる「科孊蚈算」を数倀的にモデル化するために蚭蚈されたした。 圓時、科孊コンピュヌタヌは、COBOL蚀語の「ビゞネスコンピュヌタヌ」ずは倚くの機胜が異なりたした。10進数ではなく2進数を䜿甚しおいたした。 バむトデヌタ型はありたせんでした-単語だけ。 浮動小数点挔算をサポヌトしおいたした。 そしお、圌らはより速い蚈算ず遅いI / Oを持っおいたした


通垞、このようなシミュレヌションには、できるだけ早く凊理する必芁のある数の倧きな配列を持぀倚くの線圢代数が含たれおいたした。 そしお、FORTRANは、これのためだけに最適化されたした-倚次元配列の効率的な䜿甚のため。 FORTRANには、再垰的なルヌチン、ポむンタヌ、およびレコヌドがなかっただけでなく、最初はたったくルヌチンがありたせんでした

ルヌチンがその䞭に珟れたずき、それらは配列であり埗るパラメヌタを持っおいたした。 Algol 60では、これは実際には実珟しおいたせんでした。 配列は唯䞀の非プリミティブ型であるため、配列に䜿甚できる芁玠タむプは、敎数や浮動小数点数などのプリミティブ型のみでした。


FORTRAN環境で開発された䞊列配列のメモリモデルでは、同じタむプのオブゞェクトが耇数ある堎合、それらはそれぞれ、耇数の配列で有効な数倀オフセットによっお識別されたす。 たた、特定のオブゞェクトのプラむベヌト属性の怜玢には、このオブゞェクトのむンデックスを䜿甚しおこの属性の配列にむンデックスを付けるこずが含たれたす。 1950幎代から少し離れお、デヌタを構造化するために䞊列配列に付着しお配列を圢成できるプリミティブタむプのシンボルを䜿甚できるようにした堎合、次のように前の䟋から口座名矩人の2番目の名前を決定できたす。

  1. IM = IMDNAMICCHLDIACCTN
    IA = ISTRIM
    IE = ISTRIM + 1
    配列のむンデックス付けのこれら4぀の操䜜の埌、アカりント所有者の2番目の名前はCCHARS配列の文字[IA、IEになりたす。
  2. IM = IMDNAMIACCTN、アカりント所有者の属性に個別の文字セットがない堎合は、以前のバヌゞョンのように進みたす。
  3. IMDNAMの代わりに、各アカりント所有者の2番目の名前に1぀の12文字の列を持぀、N * 12の文字の配列であるCMDNAMを䜿甚したす。

このメモリモデルでは、サブルヌチンは、匕数ずしお枡された配列内の任意のむンデックスにアクセスしたり、他の方法でアクセスしたり、ランダムな順序で䜕床でも読み曞きしたりできたす。

これはたさに「どの蚀語でもFORTRANで蚘述できる」ずいうフレヌズの意味です。ほずんどすべおのプログラミング蚀語にはプリミティブ型の配列がありたす。 アセンブラヌやForthでも、配列を䜜成するのは簡単です。 Awk、Perl4、およびTclは、オブゞェクトグラフ蚀語ではないため、ファヌストクラスオブゞェクトではない蟞曞も提䟛したすが、配列の代わりに正垞に機胜しおオブゞェクトの属性を栌玍し、敎数ではなく文字列でオブゞェクトを識別できたす。

興味深いこずに、マシンレベルでは、単玔な堎合、䞊列配列は、ネストされたモデルのように、ポむンタヌを介しお参照される構造芁玠ずほが同じコヌドを生成したす。 たずえば、ここでb->foo 、ここでbは32ビットメンバヌfooを持぀構造䜓ぞのポむンタです。

 40050c: 8b 47 08 mov 0x8(%rdi),%eax</code>    <code>foos[b]</code>,  b —    foos,   32-  : <source>400513: 8b 04 bd e0 d8 60 00 mov 0x60d8e0(,%rdi,4),%eax 

どちらの堎合も、必芁な属性を衚す即時定数をレゞスタ内の倉数に远加したす。これは、怜蚎しおいるオブゞェクトを瀺したす。 2番目の堎合の違いは、むンデックスに芁玠のサむズを掛けお、盎接定数がわずかに倧きくなるこずです。

( , , , , ).

. . , , , .

, cache-friendly, , , , ( — , ). , , , : sum covariance, .

: , .

, . , , , . , (type error) — , — . (, ). , , , , ( ), , (nested-record model).

, , , , .

FORTRAN — , . Octave, Matlab, APL, J, K, PV-WAVE IDL, Lush, S, S-Plus R . Numpy, Pandas OpenGL — «» , Perl4, awk, Tcl, , - . , . Pandas, K - (parallel-dictionary variant) , .

: CPU , GPU SIMT-, CPU SIMD- ALU . , «, » (data-oriented design) ( ) « » (entity systems). , «» .

: Lua, Erlang Forth?


: (record), . , , :


Lua Erlang - . Forth . , , - -- , . -- Linda, .

.


Unix — ( ). , — (, , ), , , ( ). ( , ). , .

, . MapReduce , lex, , .

Python, (forward iterators) C++ STL, (forward ranges) D, Golang — , .

, ? (, ) . . empty, get, ``put, , , Python - :

 def merge(in1, in2, out) { have1 := 0; have2 := 0; while !empty(in1) || !empty(in2) { if 0 == have1 && !empty(in1) { val1 := get(in1); have1 := 1; } if 0 == have2 && !empty(in2) { val2 := get(in2); have2 := 1; } if 0 == have1 { put(out, val2); have2 := 0; } else { if 0 == have2 || val1 < val2 { put(out, val1); have1 := 0; } else { put(out, val2); have2 := 0; } } } } 

, , . , . , . in1, out .. - , . ( Unix- Unix-: ). , , .

(multithreaded) (control flow system), (threads), , (empty streams block), . ; , . , , .

- (π-calculus) — , . , (concurrent) - (channel-oriented) λ-. :

Q . この堎合

  • P|Q , P Q, ;
  • a(x).P , , , , ;
  • ā〈x〉.P , , , - , .
  • (Îœa)P , — ;
  •  , ;
  • P + Q , P Q;
  • 0 , .

-:

!incr(a, x).ā〈x+1〉 | (Îœa)( i̅n̅c̅r̅〈a, 17〉 | a(y) )

«» , incr , , +1 . , «». 17 incr, , , y.

-, , , , . , (labeled graphs)! , .

« », NSA, Apache NiFi, Unix---.

Multics: (string-labeled tree) blob-


Unix ( Windows, MacOS, Multics) — , , shell-. - , — , «» - , « », ( ). , « », — .

() , ! , , , , . , () «» «». Unix , , , , .

— . , , , , , . , , .

.

, . - MUMPS, ( «» 4096 , «», « »). IBM IMS, , , «». . (Mark Lentczner) , - , Wheat. - PHP. Wheat «» «» ( , ). « » , . . Wheat , , - .

SQL: —


, .

« » «» «». cos — : Ξ cos(Ξ) . Cos-1 — : cos⁻¹(0.5) , , - . cos , : (0, 1), (π/2, 0), (π, -1), (3π/2, 0) . — : (1, 0), (0, π/2), (-1, π), (0, 3π/2) .

, , , , : n- n. , : (0, 1, 0), (π/2, 0, 1), (π, -1, 0) ..

cos, .

, , , permissions.sqlite Firefox:

 sqlite> .mode column sqlite> .width 3 20 10 5 5 15 1 1 sqlite> select * from moz_hosts limit 5; id host type permi expir expireTime ai --- -------------------- ---------- ----- ----- --------------- — - 1 addons.mozilla.org install 1 0 0 2 getpersonas.com install 1 0 0 5 github.com sts/use 1 2 1475110629178 9 news.ycombinator.com sts/use 1 2 1475236009514 10 news.ycombinator.com sts/subd 1 2 1475236009514 

, , id ; host(1) addons.mozilla.org, host(2) getpersonas.com, type(5) sts/use. -.

. , host(9), host⁻¹('news.ycombinator.com'), :

 sqlite> select id from moz_hosts where host = 'news.ycombinator.com'; id --- 9 10 

, :

 sqlite> .width 0 sqlite> select min(expireTime) from moz_hosts where host = 'news.ycombinator.com'; min(expireTime) --------------- 1475236009514 

, SQL, («» «»), , , id . - . :

 select accountholder.middlename from accountholder, account where accountholder.id = account.accountholderid and account.id = 3201 

, , , - .

SQL — , . .

Lisp, FORTRAN C, SQL , . , . SQL-, , , , (, - PL/SQL).

. , , .

SQL - : , ( , , ); ( , , COBOL). .

SQL, , :

 for (int i = 0; i < moz_hosts_len; i++) { if (0 == strcmp(moz_hosts_host[i], "news.ycombinator.com")) { results[results_len++] = moz_hosts_id[i]; } } 

, SQL : / (unmanageable) . SQL:

 select accountholder.middlename from accountholder, account where accountholder.id = account.accountholderid 

- :

 int *fksort = iota(account_len); sort_by_int_column(account_accountholderid, fksort, account_len); int *pksort = iota(accountholder_len); sort_by_int_column(accountholder_id, pksort, accountholder_len); int i = 0, j = 0, k = 0; while (i < account_len && j < accountholder_len) { int fk = account_accountholderid[fksort[i]]; int pk = accountholder_id[pksort[j]]; if (fk == pk) { result_id[k] = fk; result_middle_name[k] = accountholder_middlename[pksort[j]]; k++; i++; // Supposing accountholder_id is unique. } else if (fk < pk) { i++; } else { j++; } } free(fksort); free(pksort); 

iota :

 int *iota(int size) { int *results = calloc(size, sizeof(*results)); if (!results) abort(); for (int i = 0; i < size; i++) results[i] = i; return results; } 

sort_by_int_column :

 void sort_by_int_column(int *values, int *indices, int indices_len) { qsort_r(indices, indices_len, sizeof(*indices), indirect_int_comparator, values); } int indirect_int_comparator(const void *a, const void *b, void *arg) { int *values = arg; return values[*(int*)a] — values[*(int*)b]; } 

SQL- , , , . , .

, SQL — , , , . , , — , , , , . , , .

Prolog miniKANREN, . miniKANREN , , .

(constraint programming), («», ), . , , , SAT SMT.

Source: https://habr.com/ru/post/J323624/


All Articles