So sick! Posted December 23, 2009 Report Share Posted December 23, 2009 (edited) Man nepieciešams skripts, kurš uzģenerēs kodu pēc lietotāja pieprasījuma. Lietotājs kodu ieliek savā lapā un parādas banneris ar linku piem. http://lapa.lv/b.php?banner=big&lid=1 un uzspiežot uz bannera lietotājam ar id 1 pieskaitās 5punkti. Kodēt es māku, bet man vajag arī izdomāt kā lai izdara tā, ka ja no viena ip 2x uzspiež, tad 2. reizē nepieskaita tos 5punktus? Tātad palīdziet man lūdzu ar šīm 2 lietām:pats skrips, ip aizsardzība. Aptuveni ka varetu izskatities: <? connect_to_db(); $lid = $_GET['lid']; $banner_izm = $_GET['banner']; $ip = $_SERVER['REMOTE_ADDR']; $date = date(Y-m-d); $r = mysql_query("SELECT * FROM advertise, users WHERE users.id=$lid AND advertise.izm=$banner_izm"); $row = mysql_fetch_array($r); mysql_query("INSERT INTO advertise (ip,date,lid) VALUES ($ip, $date, $lid)"); $points = $row['points']; $points_new = $points+5; mysql_query("UPDATE users SET points=$points_new WHERE id=$lid"); //If ip fignjas te.. //Redirekts uz indexu talak, bet to nerakstishu.. ?> Edited December 23, 2009 by So sick! Quote Link to comment Share on other sites More sharing options...
marcis Posted December 23, 2009 Report Share Posted December 23, 2009 Varbūt norādi uz konkrētākām lietām, kuras nevari izdomāt kā realizēt. Linka ģenerēšana, punktu pieskaitīšana, ip nočekošana? Quote Link to comment Share on other sites More sharing options...
So sick! Posted December 23, 2009 Author Report Share Posted December 23, 2009 (edited) Kā lai pārbauda par to ip... Es domāju ka kaut kā šādi ne? <? $d = mysql_query("SELECT ip,date FROM advertise WHERE ip=$ip"); $d2 = mysql_result($d); $date = $d2['date']; if($date > date(Y-m-d)){ //pievieno punktus }else{ //nepievieno punktus } ?> Edited December 23, 2009 by So sick! Quote Link to comment Share on other sites More sharing options...
Grey_Wolf Posted December 24, 2009 Report Share Posted December 24, 2009 $d = mysql_query("SELECT ip,date FROM advertise WHERE ip=$ip"); ?> spriezjot pec shii tu ip glba kaa stringu ?? ja jaa tad 1. pie parbaudes trukst pedinju ip='$ip'"); 2. ip labak ir glabat kaa INT unsignet, lai parverstu UZ/ NO izmanto SQL f-jas INET_ATON() un INET_NTOA() Quote Link to comment Share on other sites More sharing options...
So sick! Posted December 24, 2009 Author Report Share Posted December 24, 2009 Es jav visu esmu izdomājis.. Dabūšu ip un pārveidošu par INT ar INET_ATON. Tad to INT saglabāšu datubāzē un pārbaudi veikšu pārveidojot apmeklētāja ip arī par cipariem. Ja tādi cipari jav būs datubāzē ar šodienas datumu, tad nepieskaitīs punktus, bet ja nebūs ar šodienas datumu, tad pieskaitīs.. :) Quote Link to comment Share on other sites More sharing options...
2easy Posted December 24, 2009 Report Share Posted December 24, 2009 ip labak ir glabat kaa INT unsignet, lai parverstu UZ/ NO izmanto SQL f-jas INET_ATON() un INET_NTOA() un kur palika pamatojums? ;) tā konvertēšana tač ir papildus slodze mysql serverim un papildus darbs programmētājam (sīkums, bet tomēr) vai tiešām pāris baitu dēļ tas ir vajadzīgs? anyway tas ir ļoti mazs procents no kopējā storage (pārējiem datiem dažādos teksta laukos) man liekas, ka mūdienās vieta vairs nav problēma (hdd,ram ir lēti) taču servera jauda, kas ir vajadzīga, lai vienlaicīgi apkalpotu daudz lietotājus gan pagaidām vēl nav pārpilnībā. es drīzāk atslogotu cpu no konvertācijas (bez kuras var iztikt) un rakstītu Ip varchar(15) Quote Link to comment Share on other sites More sharing options...
Kavacky Posted December 25, 2009 Report Share Posted December 25, 2009 Matemātiskās operācijas labāk padodas uz int tipiem. PS: 4 vs 15 baiti - 3.75 reižu konstants ietaupījums arī nav slikti. Quote Link to comment Share on other sites More sharing options...
Grey_Wolf Posted December 25, 2009 Report Share Posted December 25, 2009 (edited) un kur palika pamatojums? ;) Tieshi delj noslodzes, jo vai saliidzinat 15 zimju Char lauku , vai 1 Integer, kas notiek Vismaz 15X atrak (Vismaz!!!) IP adreses parversana Integer ir diezgan primitiiva operacija, vismaz Kompim noteikti (reali taa ir vienkarsha baitu parcelsana, kas aiznjems ~~~4 Procha taktiis (ja pat tik daudz) Ja vel laukus tiek indekseets tad vietas ieguvums buus arii vismaz 15X reizju lielaks ( vai indeksee CHAR vai Integer) -- Kavacky nevis 15 Bet gan 16( viens baits faktiskajam lauka garumam), jo diezvai vinsg glabas CHAR laukaa ( ja parejie buus Warchar tad CHAR vispar neies ) Bet nu vieta tiesam nebuutu tas butiskakais, ja vien ieraksti nesniegsies miljonos So sick! --> tos INET_ATON() un INET_NTOA() izmanto pa taisno Kverijaa, pat nekas nav japarveido ar PHP ;) UPDATE xx SET cc=cc+1 WHERE ip=INET_NTOA('123.123.123.0') un SELECT INET_ATON(ip) AS gatava_ip FROM xx un ja kas PHP arii ir liidzigas f-jas ... Edited December 25, 2009 by Grey_Wolf Quote Link to comment Share on other sites More sharing options...
bubu Posted December 25, 2009 Report Share Posted December 25, 2009 Ja vel laukus tiek indekseets tad vietas ieguvums buus arii vismaz 15X reizju lielaks ( vai indeksee CHAR vai Integer) Esi pārliecināts? Es kautkā šaubos par šo apgalvojumu - es teiktu, ka ieguvums labi ja būs 1.5x Quote Link to comment Share on other sites More sharing options...
2easy Posted December 26, 2009 Report Share Posted December 26, 2009 Matemātiskās operācijas labāk padodas uz int tipiem. PS: 4 vs 15 baiti - 3.75 reižu konstants ietaupījums arī nav slikti. iekš "WHERE ip=$ip" kur te ir matemātiska operācija? salīdzināšana? ok, lai tā būtu konstants ietaupījums? hmm, man gan drīzāk liekas, ka mainīgs (atkarībā no datiem) pašam ar asm nav pieredzes, bet man liekas, ka divu 4x baitīgu integeru salīdzināšana varētu būt 1x cpu instrukcija, savukārt 15x baitīgus stringus iespējams salīdzina pa baitam: kamēr tie ir vienādi, tikmēr iet uz priekšu, līdz visi baiti ir salīdzināti. bet varbūt arī stringus salīdzina, cpu reģistros katrā taktī uzreiz iedzenot pa 4x baitiem? tādējādi stringu salīdzināšanai vajadzētu būt ilgākai par integeru salīdzināšanu tikai tad, ja abu stringu pirmie baiti sakrīt, jo tad ir jāveic vairākas low level salīdzināšanas whatever, nav ko daudz teoretizēt. labāk skatāmies, cik ātri viss notiek reālā darbībā $gnTime = 0; function utime() {list($sSecU, $sSec) = explode(' ', microtime()); return $sSec + $sSecU;} // izdod pašreizējo laiku: sekundes + mikrosekundes (aiz "komata") function timerSet() {global $gnTime; $gnTime = utime();} function timerGet() {global $gnTime; return round(utime() - $gnTime, 6);} function timerEcho($sInfo = '') {printf('%s%.4f<br />', $sInfo, timerGet());} // parāda laiku ar precizitāti līdz 100 mikrosekundēm (ilgākām darbībām). lielākas precizitātes mērījumiem desmitos mikrosekunžu (vai vēl mazāk) ir jāņem vērā arī pašas funkcijas izsaukuma laiks (tb tad būtu jāaprēķina function call overhead) function qs($s) { // sagatavo stringu priekš sql query return is_null($s) ? 'NULL' : "'" . mysql_real_escape_string($s) . "'"; } function go($sSql) { // mysql query ar error reportingu $h = mysql_query($sSql) or die('<b>mysql error ' . mysql_errno() . ':</b> ' . mysql_error() . '<br /><b>query:</b> ' . substr($sSql, 0, 1000)); return $h; } function ipRand() {return rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255) . '.' . rand(0, 255);} function ipLoad() { // izveido/ielādē testa datus: 100 000 random ip adreses 3x dažādos tabulas laukos $h = fopen('load.sql', 'w'); fwrite($h, 'INSERT t (Ip, Ip2, Ip3) VALUES ('); for ($i = 0; $i < 100000; $i++) { $sIp = ipRand(); fwrite($h, ($i ? '),(' : '') . qs($sIp) . ',' . qs($sIp) . ',' . sprintf('%u', ip2long($sIp))); } fwrite($h, ')'); fclose($h); go('DROP TABLE IF EXISTS t'); go('CREATE TABLE t (Ip varchar(15) NOT NULL, Ip2 char(15) NOT NULL, Ip3 int UNSIGNED NOT NULL) ENGINE=MyISAM'); go('ALTER TABLE t ADD INDEX (Ip)'); go('ALTER TABLE t ADD INDEX (Ip2)'); go('ALTER TABLE t ADD INDEX (Ip3)'); //go('SET GLOBAL max_allowed_packet = 104857600'); // vajag priekš lieliem query, taču uz hostiem var nebūt tiesību mainīt šo settingu. tad atliek localhost go(file_get_contents('load.sql')); } function ipLoadTimer() { // ielādē datus un parāda, cik tas paņem laiku timerSet(); ipLoad(); timerEcho('IP ielāde: '); } function ipSelTimer() { // selectē ip no dažādiem laukiem, lai noskaidrotu, no kura to var izdarīt visātrāk list($sIp) = mysql_fetch_row(go('SELECT Ip FROM t LIMIT ' . rand(0, 99999) . ',1')); // paņem random ip, kuru pēc tam "meklēs" timerSet(); $h = go('SELECT * FROM t WHERE Ip = ' . qs($sIp)); timerEcho('Ip select: '); timerSet(); $h2 = go('SELECT * FROM t WHERE Ip2 = ' . qs($sIp)); timerEcho('Ip2 select: '); timerSet(); $h3 = go('SELECT * FROM t WHERE Ip3 = ' . sprintf('%u', ip2long($sIp))); timerEcho('Ip3 select: '); timerSet(); $h4 = go('SELECT * FROM t WHERE Ip3 = INET_ATON(' . qs($sIp) . ')'); timerEcho('Ip3 select2: '); } ini_set('max_execution_time', 300); ipLoadTimer(); // izpilda 1x, lai ielādētu testa datus (pēc tam aizkomentē) ipSelTimer(); // izpilda daudzreiz, kamēr iegūst pietiekami ticamu vidējā laika novērtējumu /* aptuvens vidējais rezultāts uz mana pc: // 10 000 rindas IP ielāde: 0.7000 Ip select: 0.0008 Ip2 select: 0.0008 Ip3 select: 0.0006 Ip3 select2: 0.0006 // 100 000 rindas IP ielāde: 6.0000 Ip select: 0.0008 Ip2 select: 0.0008 Ip3 select: 0.0006 Ip3 select2: 0.0006 // 1 000 000 rindas (brīžiem diezgan nestabili rezultāti, tāpēc svārstīgākajiem rezultātiem ir laika intervāls, nevis viens aptuvenais laiks) IP ielāde: 45s (load.sql izveidošana) + 2min (load.sql -> mysql) Ip select: 0.0030 Ip2 select: 0.0030 - 0.0300 Ip3 select: 0.0025 Ip3 select2: 0.0025 */ jāsaka gan, ka 1 000 000 rindas izdevās iedabūt db tikai no komandrindas: > mysql -u root -p < load.sql INSERTam pieliekot priekšā db selektu: USE test; jo, ieraugot ~43MB lielu query, mysql vnk aizbēga "MySQL server has gone away" :D:D:D, neskatoties uz to, ka max_allowed_packet ir uzlikts 100MB ;) turklāt pat no komandrindas tas nebija tik gludi. tas tādēļ 512MB RAM, ar ko šim testam ir par maz, jo load laikā mysqld-nt.exe izaug pāri par 500MB (RAM + VM). vispār, kad tabulas izmērs aiziet desmitos MB (pāri par 100 000 rindām atkarībā no testa datu apjoma), tad es to vairs nevaru normāli notestēt, jo ir nestabili rezultāti, ram pārslodze... secinājumi: 1) ieguvums no Ip int UNSIGNED salīdzinot ar Ip varchar(15) ir tiešām mikroskopisks: tabulām no 10k - 100k rindām tas ir 100 līdz 200 mikrosekundes (turklāt tas ir uz parasta ne pārāk jauna mājas kompja P4 2.6GHz, 512MB DDR). vienīgi sākot no miljons rindām parādās kāda milisekunde atšķirība! :D mēģinot padarīt šo testu objektīvāku, atsevišķi notestēju arī mazāk rindas (10k) taču garākas - ar extra lauku varchar(200) ar random tekstu. un kā izrādījās, selectus tas nekādi neietekmēja (skaidrojums: WHERE skatās iekš index, un šajā gadījumā pašas tabulas izmēram nav nozīme) 2) atšķirību starp Ip varchar(15) un Ip char(15) nevarēja pamanīt 3) tāpat arī tā īsti nevarēja pamanīt atšķirību starp ip konvertēšanu php/mysql pusē ar ip2long()/INET_ATON() 4) atšķirība starp 10k un 100k rindām arī nebija īpaši jūtama (10k rindām daži rezultāti epizodiski bija mazāki, nekā mēdz būt mazākie rezultāti 100k rindām, taču vidēji tas pats) anyway Vilks, tā jau tu domā pareizi, ka ar int ir ātrāk. tikai tas ieguvums ir tik niecīgs, ka to vispār var neņemt vērā. tas tā varētu būt tāpēc, ka mysql iekšpusē ir uz viskko nooptimizēts. un lai arī ārēji/teorētiski liekas, ka vienam risinājumam vajadzētu būt daudz ātrākam, taču praksē tas tā var nebūt... gan jau ka ir pielietojumi, kur šāds ip adreses formāts dod jūtamākus ieguvumus, taču šis nav tas gadījums ;) protams, pastāv arī maza varbūtība, ka kādam citam šis tests dotu pavisam citus rezultātus nekā man un tad jau sazin, kur būtu patiesība... :D:D:D btw, pa "Discovery Channel" iet tāda raidījumu sērija "MythBusters", kur džeki lauž vienu stereotipu pēc otra... vnk šitais te sāk atgādināt to raidījumu :P kr4 iesaku praktiski pārbaudīt lietas. datorzinātne ir gan eksakta, gan empīriska, tāpēc vajag experimentēt, nevis tikai gudri spriedelēt ;) Quote Link to comment Share on other sites More sharing options...
Grey_Wolf Posted December 26, 2009 Report Share Posted December 26, 2009 (edited) Esi pārliecināts? Es kautkā šaubos par šo apgalvojumu - es teiktu, ka ieguvums labi ja būs 1.5x nu Ok. ne 15X reizju bet nu krietni. Jo Salidzinat 15X + 1 (garuma notiksana) baitus vai 4 ir tomer atskjiriiba .. Dizvai nepiekritisi ka pat 1 simbola Char un 1 Integer atrashana buus par labu Integer Tas taa nevelos ipashi ielaisties 'Religiska' disputaa... ------ gan jau ka ir pielietojumi, kur šāds ip adreses formāts dod jūtamākus ieguvumus, taču šis nav tas gadījums ;) protams, pastāv arī maza varbūtība, ka kādam citam šis tests dotu pavisam citus rezultātus nekā man un tad jau sazin, kur būtu patiesība... :D:D:D Aha ir gan cits pielietojums ;) Saucas DNS serveri .. -- Neba 10-100Rindinjas ir nopietnis raditajs DB tabulai .. Ja lapa buus peitiekami apmekleta, tad atri vein savakas taas 1M rindinjas, un tad jau rezultatas buus juutams.. Piedevam ier slikta prakse nepareizi glabat datus.. Jo iesakot ka CHAR( Warchar) ir labakais veids kaa glabat IP tad .... ( sliktie vardi izlaisti, bet saglabajas domas no tiem kam kautko tadu naksies pielabot, {nedod dies` konvertet daudzu M garu DB tabli..} ) --- Edited December 26, 2009 by Grey_Wolf Quote Link to comment Share on other sites More sharing options...
2easy Posted December 26, 2009 Report Share Posted December 26, 2009 The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet. - Michael A. Jackson Quote Link to comment Share on other sites More sharing options...
So sick! Posted December 26, 2009 Author Report Share Posted December 26, 2009 Es uztaisiju visu tieši tā kā man vajag.. :) Varat taisīt ciet šo topiku.. :) Quote Link to comment Share on other sites More sharing options...
2easy Posted December 26, 2009 Report Share Posted December 26, 2009 a mums vēl gribējās paturpināt tēmu ;) Quote Link to comment Share on other sites More sharing options...
bubu Posted December 26, 2009 Report Share Posted December 26, 2009 Jo Salidzinat 15X + 1 (garuma notiksana) baitus vai 4 ir tomer atskjiriiba .. Bet tas jau ir tikai tad, ja datus salīdzina pa tiešo. Ja lauki ir indeksēti, tad tie netiek salīdzināti pa tiešo - tiek salīdzināti to heši. Un integera hešs ir tikpat liels/ātrs kā stringa hešs salīdzināšanā. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.