{"id":469,"date":"2017-02-12T16:21:20","date_gmt":"2017-02-12T14:21:20","guid":{"rendered":"https:\/\/moijari.com\/?p=469"},"modified":"2019-11-22T01:53:27","modified_gmt":"2019-11-21T23:53:27","slug":"hashin-kaytto-tertun-kyselyn-kasittelyssa","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=469","title":{"rendered":"Hash:in k\u00e4ytt\u00f6 tertun kyselyn k\u00e4sittelyss\u00e4"},"content":{"rendered":"<p>Kaikki oikeudet tietenkin pid\u00e4tet\u00e4\u00e4n. Viimeinen versio ohjelmasta l\u00f6ytyy seuraavasta linkist\u00e4: <a href=\"https:\/\/moijari.com:5002\">moijari.com:5002<\/a><\/p>\n<p>T\u00e4ll\u00e4 hetkell\u00e4 ajattelen ett\u00e4 terttu jakautuu kahteen osaan, sovellusosaan ja tietokantaosaan. Sovellusosa sis\u00e4lt\u00e4\u00e4 kaikki sovelluskohtaiset asiat, kuten tertussa olevat logon-rutiini, sovellus-rutiini, prosessien jatkaminen, talletus-rutiini ja nuo sarakkeiden siirtelyt prosessien yhteydess\u00e4.<\/p>\n<p>Tietokantaosa sis\u00e4lt\u00e4\u00e4 toiminnot fetch ja save, jotka ovat yksinkertaisia toimintoja. Fetchill\u00e4 luetaan rivej\u00e4 ja save:lla talletetaan niit\u00e4.<\/p>\n<h2>Fetch lyhyesti<\/h2>\n<p>(polveilevaa jaarittelua) Fetch koostuu vaiheista, Ensimm\u00e4inen vaihe muodostaa asiakkaan antamasta kyselyst\u00e4 vakiomuotoiset versiot. T\u00e4ss\u00e4 yksi versio kyselyn normalisointirutiinista, voit itse kokeilla tehd\u00e4 muut versiot voi olla my\u00f6s ett\u00e4 min\u00e4 lis\u00e4\u00e4n koodia postin loppuun..<\/p>\n<pre>void skk_querystring1(char *query, unsigned char *newquery)\r\n{\r\n  int value;\r\n  unsigned char *p,*q;\r\n  HashCtx ctx;\r\n\r\n  p=query;\r\n  q=newquery;\r\n\r\n  skk_skipwhite(&amp;p);\r\n  while(*p!='\\0') {\r\n    if(*p=='\\'') {\r\n      *q++=*p++;\r\n      while(*p!='\\'' &amp;&amp; *p!='\\0')\r\n        *q++=*p++;\r\n      *q++='\\'';\r\n      if(*p=='\\'')\r\n        p++;\r\n    } else if(*p=='=') {\r\n      p++;\r\n      *q++=' ';\r\n      *q++='=';\r\n      *q++=' ';\r\n    } else if(*p=='\\\"') {\r\n      p++;\r\n      value=0;\r\n      while(*p!='\\\"' &amp;&amp;*p!='\\0') {\r\n        p++;\r\n        value=1;\r\n      }\r\n      if(*p=='\\\"')\r\n        p++;\r\n        if(value==1)\r\n          *q++='?';\r\n    } else if(*p==',') {\r\n      p++;\r\n      *q++=',';\r\n      *q++=' ';\r\n    } else if(*p==' ' || *p=='\\t') {        \r\n      skk_skipwhite(&amp;p);\r\n      *q++=' ';\r\n    } else\r\n      p++;\r\n  }\r\n  *q='\\0';\r\n}<\/pre>\n<p>Huomaathan ett\u00e4 t\u00e4m\u00e4 normalisointi normalisoi my\u00f6s &#8216;m\u00e4\u00e4r\u00e4&#8217;=&#8217;isotilaus&#8217;. Ja ett\u00e4 toisaalta se ei toimi kyselylle &#8216;m\u00e4\u00e4r\u00e4'&lt;&#8216;saldo&#8217;. T\u00e4m\u00e4 on viel\u00e4 hiukan hakusessa.<\/p>\n<p>Seuraavasta kyselyst\u00e4 (&#8216;asiakasnumero&#8217; = &#8220;1000&#8221; ,\u00a0 &#8216;asiakkaan nimi&#8217;) tulostetaan ainakin seuraavat versiot: versioissa vakiotoiminta on siten, ett\u00e4 vaihdetaan useamman v\u00e4lily\u00f6nti-tabi yhdistelm\u00e4t yhteen v\u00e4lily\u00f6ntiin. Yht\u00e4suuruusmerkki vaihdetaan v\u00e4lily\u00f6nti yht\u00e4suuruusmerkki-v\u00e4lily\u00f6ntiin. Hipsulla &#8216;\\&#8221; annetut kent\u00e4n nimet tallennetaan siten ett\u00e4 ne joko alkavat rivin alusta, tai erotetaan toisista sanoista v\u00e4lily\u00f6nnein. Lainausmerkill\u00e4 &#8216;&#8221;&#8216; annetut kent\u00e4n arvot siirret\u00e4\u00e4n samalla tavalla kuin hipsu kent\u00e4t. Samoin kyselyn kent\u00e4t lajitellaan aakkosj\u00e4rjestykseen. Mallina olevassa kyselyss\u00e4 olevat kent\u00e4t ovat tietenkin jo aakkosj\u00e4rjestyksess\u00e4.<\/p>\n<p>(&#8216;asiakasnumero&#8217;, &#8216;asiakkaan nimi&#8217;)<\/p>\n<p>t\u00e4ll\u00e4 versiolla voidaan tarkistaa, onko tietueet talletettu siten, ett\u00e4 yhdess\u00e4 hash koodilla hajasijoitetussa tietoryhm\u00e4ss\u00e4 on kaikki tietueet. Esimerkkin\u00e5 voisi olla:<\/p>\n<p>(&#8216;kuukauden numero&#8217;=&#8221;1&#8243;, &#8216;kuukauden nimi&#8217;=&#8221;Tammikuu&#8221;)<br \/>\n(&#8216;kuukauden numero&#8217;=&#8221;2&#8243;, &#8216;kuukauden nimi&#8217;=&#8221;Helmikuu&#8221;)<\/p>\n<p>Tietueet jatkuvat tietysti samalla tavalla loppuun asti. Kun tiedosto avataan, sielt\u00e4 valitaan kyselyyn m\u00e4ts\u00e4\u00e4v\u00e4t tiedot.<\/p>\n<p>Toinen vakioitu versio kyselyst\u00e4 on seuraavana:<\/p>\n<p>(&#8216;asiakasnumero&#8217; = ?, &#8216;asiakkaan nimi&#8217;)<\/p>\n<p>T\u00e4ll\u00e4 hash koodilla l\u00f6ydet\u00e4\u00e4n tieto siit\u00e4, onko t\u00e4m\u00e4 tieto talletettu tuossa muodossa, eli siis kannattaako (&#8216;asiakasnumero&#8217;= &#8220;1000&#8221; &#8220;asiakkaan nimi&#8221;) tyylist\u00e4 kysely\u00e4 hakea. Ilmeisesti kaikilla tietojen perusavaimilla voi tai pit\u00e4\u00e4 olla t\u00e4m\u00e4 versio. Huomaa pienet tiedostot ja ensimm\u00e4inen kyselyversio.<\/p>\n<p>Seuraava versio kyselyst\u00e4 on malli, jolla hajasijoitetusta &#8220;tietokannasta&#8221; haetaan tieto:<\/p>\n<p>(&#8216;asiakasnumero&#8217; = &#8220;1000&#8221; ,\u00a0 &#8216;asiakkaan nimi&#8217;)<\/p>\n<p>Ja t\u00e4ss\u00e4kin vakiomuotoisesta kyselyst\u00e4 muodostetaan hash koodi, josta tehd\u00e4\u00e4n x syvyyksinen hakemistorakenne ja jos tiedosto l\u00f6ytyy, sielt\u00e4 pit\u00e4isi l\u00f6yty\u00e4 kyselyn tulos. Eli kyselyn vastaukseen tarvitaan n 4 tiedoston avausta, hash koodin laskentaa ja kyselymerkkijonon normalisointia.<\/p>\n<p>Toisessa vaiheessa tarkistetaan l\u00f6ytyyk\u00f6 kyselyn perusteella avain muistista, muistissa olevat kyselyt talletetaan muodossa:<\/p>\n<pre>struct query {\r\n    unsigned char *query;\r\n    struct set *sets;\r\n    struct query *next;\r\n}:<\/pre>\n<p>Haetaan vain muistilista l\u00e4pi &#8220;tarkalla&#8221; kyselyversiolla, jos kysely l\u00f6ytyy listasta, sill\u00e4 on t\u00e4ss\u00e4 rakenteessa sets kent\u00e4ss\u00e4 ratkaisu. Jatkossa lis\u00e4t\u00e4\u00e4n viel\u00e4 viimeiset tapahtumat eli muutokset lokista. (katso perusavain m\u00e4\u00e4rittely jatkossa)<\/p>\n<p>Muistissa olevat kyselyt pit\u00e4\u00e4 j\u00e4rjest\u00e4\u00e4 siten ett\u00e4 usein k\u00e4ytetyt kyselyt ovat ensimm\u00e4isen\u00e4 listassa, silloin voidaan poistaa harvoin k\u00e4ytetyt kyselyt siten, ett\u00e4 poistetaan viimeiset kysely vastaus parit.<\/p>\n<p>Kolmannessa vaiheessa haetaan pelk\u00e4t kenttien nimet sis\u00e4lt\u00e4v\u00e4ll\u00e4 versiolla olisiko kysymys pienest\u00e4 taulusta (tai miksei suuremmastakin, jos kyselyn suoritusnopeudella ei ole v\u00e4li\u00e4). Jos tiedosto l\u00f6ytyi, me saamme siit\u00e4 vastauksen. Vastaukseen lis\u00e4t\u00e4\u00e4n viel\u00e4 viimeisten lokitapahtumien muutokset.<\/p>\n<p>Nelj\u00e4nness\u00e4 vaiheessa haetaan kys\u00e4ri(?)versiolla onko meill\u00e4 ratkaisua t\u00e4lle kyselymuodolle, jos on k\u00e4ytet\u00e4\u00e4n kenttien arvot sis\u00e4lt\u00e4v\u00e4\u00e4 versiota, taas saadaan tulos, johon lis\u00e4t\u00e4\u00e4n lokitapahtumat ja palautetaan tiedot asiakkaalle (asiakasohjelmalle).<\/p>\n<p>Viidenness\u00e4 versiossa kyselyn vastaus haetaan lokista (vrt perusavain mallit).<\/p>\n<p>Kaikissa kyselymalleissa palautettava vastaus lis\u00e4t\u00e4\u00e4n muistissa olevien kyselyiden joukkoon.<\/p>\n<h2>Save<\/h2>\n<p>Save toiminto lis\u00e4\u00e4 talletuskutsussa olevat tietueet lokin loppuun ja kirjoittaa lokin levylle. Ilmeisesti jossain kohtaa kirjoitetaan n\u00e4m\u00e4 lokientrit eri talletustavoilla k\u00e4ytettyihin tiedostoihin (muisti, pieni taulu, taulu avaimella jne.)<\/p>\n<h2>Hakemistorakenne<\/h2>\n<p>Hash koodista muodostetaan hakemistorakenne seuraavasti:<\/p>\n<p>Hash koodilla: abcdefghijklmnopqrstuvwxyz hakemistorakenne voi olla: kanta\/ab\/cd\/ef\/gh\/ij\/kl\/mn\/op\/qr\/st\/uv\/wx\/yz tai kanta\/ab\/cdefghijklmnopqrstuvwxyz tai jotakin silt\u00e4 v\u00e4lilt\u00e4.<\/p>\n<h2>Perusavaimista<\/h2>\n<p>Edit: Perusavaimen k\u00e4sittelyyn on mieless\u00e4ni kaksi mallia, ensimm\u00e4inen on yksinkertainen malli, jossa tietueen avaim(ena\/ina) ovat aina saman nimiset kent\u00e4t, muilla tietueen kentill\u00e4 ei ole merkityst\u00e4, eli selvit\u00e4\u00e4n yksinkertaisella m\u00e4\u00e4rittelyll\u00e4:<\/p>\n<p>(&#8216;memberid&#8217;=&#8221;asiakasnumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)(&#8216;memberid&#8217;=&#8221;toimittajanumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;tuotenumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;tilausnumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;tilausrivin numero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;toimitusnumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;toimitusrivin numero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;laskunumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;laskurivin numero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;tapahtumanumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;tapahtumarivin numero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<\/p>\n<p>Edit: Olen yleens\u00e4 pit\u00e4ytynyt tiukasti n\u00e4iss\u00e4 kolmessa nelj\u00e4ss\u00e4 taulussa, mutta annetaan nyt hiukan ajatuksen lent\u00e4\u00e4:<\/p>\n<p>(&#8216;memberid&#8217;=&#8221;bussinumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;autonumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;toimenpidenumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;).<\/p>\n<p>Edit: Voit keksi\u00e4 itse oman alasi tietueiden avaimet. Toisessa mallissa kaikki tietueen kent\u00e4t m\u00e4\u00e4rittelev\u00e4t tietuetyypin, ja n\u00e4ist\u00e4 kentist\u00e4 jotkut ovat avaimia, esimerkiksi:<\/p>\n<p>(&#8216;memberid&#8217;=&#8221;asiakasnumero&#8221;, &#8216;key&#8217;=&#8221;1&#8243;)<br \/>\n(&#8216;memberid&#8217;=&#8221;asiakkaan nimi&#8221;)<br \/>\n(&#8216;memberid&#8217;=&#8221;asiakkaan osoite&#8221;)<br \/>\n(&#8216;memberid&#8217;=&#8221;asiakkaan postitoimipaikka&#8221;)<br \/>\n(&#8216;memberid&#8217;=&#8221;asiakkaan postiosoite&#8221;)<br \/>\n(&#8216;memberid&#8217;=&#8221;asiakkaan maa&#8221;)<\/p>\n<p>Edit: Tottakai tietueella voi olla &#8216;setid&#8217; kentt\u00e4, joka nime\u00e4\u00e4 n\u00e4m\u00e4 kentt\u00e4 yhdistelm\u00e4t. Esimerkiksi edellisess\u00e4 set id voisi olla &#8216;asiakas&#8217;, Tertussa t\u00e4h\u00e4n asti on ollut vain sovelluksia, joilla voi olla otsakkeita ja rivej\u00e4.<\/p>\n<p>Edit: (out there) Toki n\u00e4ist\u00e4 voi keksi\u00e4 viel\u00e4 monimutkaisempia vaihtoehtoja, joissa esimerkiksi jonkun kent\u00e4n sis\u00e4lt\u00f6 m\u00e4\u00e4ritt\u00e4\u00e4 tietueella olevat kent\u00e4t:<\/p>\n<p>(&#8216;memberid&#8217;=&#8221;toimenpidenumero&#8221;)<br \/>\n(&#8216;memberid&#8217;=&#8221;toimenpidetyyppi&#8221;)<br \/>\n(&#8216;toimenpidetyyppi=&#8221;\u00f6ljyn vaihto&#8221;, &#8216;memberid&#8217;=&#8221;tuotenumero&#8221;)<br \/>\n(&#8216;toimenpidetyyppi=&#8221;\u00f6ljyn vaihto&#8221;, &#8216;memberid&#8217;=&#8221;huomiot&#8221;)(&#8216;toimenpidetyyppi=&#8221;renkaan vaihto&#8221;, &#8216;memberid&#8217;=&#8221;uusi paine&#8221;)(&#8216;toimenpidetyyppi=&#8221;renkaan vaihto&#8221;, &#8216;memberid&#8217;=&#8221;huomiot&#8221;)<\/p>\n<p>Edit: N\u00e4m\u00e4 tuovat monimutkaisuutta enemm\u00e4n kuin on tarpeen. T\u00e4m\u00e4n tyyppiset ratkaisut kuitenkin ratkeavat automaattisella navigaatiolla, t\u00e4ss\u00e4 vain tarvitaan tietuetta tai ainakin tuota toimenpidetyyppi\u00e4 mukaan hakuun, jossa haetaan tietueen kentti\u00e4.<\/p>\n<h2>Levytilan v\u00e4hennyst\u00e4<\/h2>\n<p>Jos kyselyyn vastataan hakemalla kyselyyn perustuvalla hash koodilla relevantit tietueet, tiedosto voi olla perinteisen terttu (tai skk1) formaatin mukaan:<\/p>\n<p>(&#8216;asiakasnumero&#8217;=&#8221;1000&#8243;, &#8216;asiakkaan nimi&#8217;=&#8221;Asiakas 1&#8243;)<\/p>\n<p>tai tiivist\u00e4\u00e4 sit\u00e4 hiukan kirjoittamalla kenttien nimet vain otsakkeeseen: (kyselyst\u00e4h\u00e4n kenttien nimi\u00e4 ei voi katsoa, koska ne ovat lajiteltuna aakkosj\u00e4rjestykseen, eli alkuper\u00e4isen kyselyn nimill\u00e4 ei ole merkityst\u00e4.<\/p>\n<p>&#8216;asiakasnumero&#8217;, &#8216;asiakkaan nimi&#8217;<br \/>\n&#8220;1000&#8221;, &#8220;Asiakas 1&#8221;<\/p>\n<h2>Tietueiden &#8220;splittaus&#8221;<\/h2>\n<p>Edit: T\u00e4m\u00e4 ajatus liittyy my\u00f6s tiedon talletustilan v\u00e4hent\u00e4miseen. Jos teemme kyselyn, Esimerkiksi:<\/p>\n<p>&#8217;tilausnumero&#8217;, &#8217;tilauksen asiakasnumero&#8217;, &#8217;tilauksen asiakkaan nimi&#8217;, &#8217;tilauksen tuotenumero&#8217;, &#8217;tilauksen tuotteen nimi&#8217;,<\/p>\n<p>kysely muodostuu otsakkeiden tiedoista ja tilausrivien tiedoista, eli kyselyn tulos on:<\/p>\n<p>&#8217;tilausnumero&#8217;=&#8221;4000&#8243;, &#8217;tilauksen asiakasnumero&#8217;=&#8221;1000&#8243;, &#8217;tilauksen asiakkaan nimi&#8217;=&#8221;Asiakas 1&#8243;, &#8217;tilauksen tuotenumero&#8217;=&#8221;3000&#8243;, &#8217;tilauksen tuotteen nimi&#8217;=&#8221;Tuote 1&#8243;<br \/>\n&#8217;tilausnumero&#8217;=&#8221;4000&#8243;, &#8217;tilauksen asiakasnumero&#8217;=&#8221;1000&#8243;, &#8217;tilauksen asiakkaan nimi&#8217;=&#8221;Asiakas 1&#8243;, &#8217;tilauksen tuotenumero&#8217;=&#8221;3000&#8243;, &#8217;tilauksen tuotteen nimi&#8217;=&#8221;Tuote 1&#8243;<br \/>\n&#8217;tilausnumero&#8217;=&#8221;4000&#8243;, &#8217;tilauksen asiakasnumero&#8217;=&#8221;1000&#8243;, &#8217;tilauksen asiakkaan nimi&#8217;=&#8221;Asiakas 1&#8243;, &#8217;tilauksen tuotenumero&#8217;=&#8221;3000&#8243;, &#8217;tilauksen tuotteen nimi&#8217;=&#8221;Tuote 1&#8243;<br \/>\n&#8230;<\/p>\n<p>Ja siin\u00e4 on otsakkeen osalta aika paljon toistoa, koska kaikki otsakekent\u00e4t ovat samat samassa tilauksessa. T\u00e4ss\u00e4 tapauksessa voitaisiin jakaa sovellus kaikkiin eri rivimalleihin, eli otsake olisi oma tietuemallinsa, rivi olisi oma tietuemallinsa, ja ne vain yhdistelt\u00e4isiin vasta luvun yhteydess\u00e4,<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kaikki oikeudet tietenkin pid\u00e4tet\u00e4\u00e4n. Viimeinen versio ohjelmasta l\u00f6ytyy seuraavasta linkist\u00e4: moijari.com:5002 T\u00e4ll\u00e4 hetkell\u00e4 ajattelen ett\u00e4 terttu jakautuu kahteen osaan, sovellusosaan ja tietokantaosaan. Sovellusosa sis\u00e4lt\u00e4\u00e4 kaikki sovelluskohtaiset asiat, kuten tertussa olevat logon-rutiini, sovellus-rutiini, prosessien jatkaminen, talletus-rutiini ja nuo sarakkeiden siirtelyt prosessien yhteydess\u00e4. Tietokantaosa sis\u00e4lt\u00e4\u00e4 toiminnot fetch ja save, jotka ovat yksinkertaisia toimintoja. Fetchill\u00e4 luetaan rivej\u00e4 ja&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=469\">Continue reading <span class=\"screen-reader-text\">Hash:in k\u00e4ytt\u00f6 tertun kyselyn k\u00e4sittelyss\u00e4<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/469"}],"collection":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=469"}],"version-history":[{"count":11,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/469\/revisions"}],"predecessor-version":[{"id":482,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/469\/revisions\/482"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}