WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Rådgivning med databas frågor. (https://www.wn.se/forum/showthread.php?t=35522)

oloflolof 2009-03-04 19:35

Hejsan alla!

Jo det är så på min sida att jag har filmer och spel.
På varje sida där ett spel/film ligger har jag denna koden för att
uppdatera klick.
Kod:

mysql_query("UPDATE onlinespel SET klick=klick +1 WHERE id =
".$onlinespel[id]." ")or die(mysql_error());

Detta har alltid funkat bra men nu är det vissa som gillar att trycka
F5 många gånger så vipps så har man kankse 50 000 klick.

Så jag tänkte göra en spärr att en person får en unik session variabel
och sen gör jag en tabell.
Kod exempel. (Finns säkert fel i den, skrev ihop lite snabbt men hoppas ni förstår.)
Kod:

// Kolla klick redan är räknat för denna person
 $sql = "SELECT COUNT(*) FROM klick WHERE
session_unik_id='$_SESSION[unik_id]' AND spel_id = '$spel_id'";
 $result = mysql_query($sql);
 if (mysql_result($result, 0) == 0) {
// Om han inte hittar någon så uppdateras klick, Annars händer inget.
mysql_query("UPDATE onlinespel SET klick=klick +1 WHERE id =
".$onlinespel[id]." ")or die(mysql_error());
// Sätter in värden i tabellen "klick" så han inte ska kunna rösta igen.


mysql_query("INSERT INTO klick( spel_id, session_unik_id ) VALUES( '$spel_id','$_SESSION[unik_id]') ") or die(mysql_error());
 }

Sen tänkte jag tömma denna tabellen var tionde minut med hjälp av
phpfil och cron.
Men hur bra är detta? Är detta resurskrävande? I dagsläget kan det ju
säkert funka men man måste ju tänka i framtiden då man kanske har
många mer besökare.
Idags läget har jag väl under 1000klick sammanlagt på dag men det kan
ju komma den dagen då man får 1000 klick under den 10 minuters
perioden och då vill man ju fortfarande att det flyter på. (Man kan ju hoppas att den tiden kommer. :) )

Eller har ni något bättre förslag?

Ja hoppas ni förstog allt detta.

MVH Olof

webbhelp 2009-03-04 19:47

Du kan väl köra med att en session startas i 10 minuter, sen efter 10 minuter kan man klicka igen och trycker man igen får man vänta i 10 minuter igen, så håller det på så.

du kan ha en array i sessionen som då får ett nytt värde vid varje klick vid nytt spel sen kolalr du om id:et finns i arrayen när man klickar

webbhelp 2009-03-04 19:53

Men du kan även köra med databas, men då kan du uppdatera alla kolumner i databasen där 10 minuter har gått sedan dom lades in och sen bara sätter du 0 på dom kolumnerna

MMC 2009-03-04 19:53

SELECT COUNT(*) ... är en väldigt billig operation om din tabell är MyISAM, så med rätt index bör inte den frågan påverka prestandan så mycket.

Men däremot tycker jag inte att tre frågor (SELECT, UPDATE och INSERT) är nödvändigt för det här användningsområdet.

Med lite högre belastning så börjar offlineuppdatering bli mer intressant, och jag skulle föreslå att du använder det här också. Du säger att du ändå ska köra ett cronskript för att tömma din klick-tabell var 10:e minut. Använd det här upplägget istället:

Vid varje sidladdning kör du en INSERT med ditt sessionsunika id, objekt-id och tidssstämpel.

Sen kör du ett cronskript som uppdaterar kolumnen för antal klick i din tabell utefter datan som finns i den här klickloggningstabellen. Ta samtidigt bort datan ur tabellen.

Fördelen med det här tillvägagångssättet är att varje sidladdning bara genererar en INSERT, samt att du när du börjar få mer trafik helt enkelt kan köra cronskriptet mer sällan för att sänka belastningen på databasservern. Får du 6000 klick i timmen spelar det kanske ingen roll om inte klickräknaren uppdateras oftare än var 10e minut, exempelvis.

oloflolof 2009-03-04 20:04

Hej MMC.

Det du skrev med offlineuppdatering låter intressant.
Men en sak jag inte förstog. Du skrev att vid varje sidladdning kan man göra en INSERT. Skulle man inte innan kunna göra en COUNT och se om den redan finns, och om det inte fanns en post med unik_id och objekt_id göra en insert?
Eller blir det fortfarande mindre resurskrävande utan count och bara en insert vid varje?

MVH Olof

Magnus_A 2009-03-04 21:24

Ett tips: Kör inte
Citat:

or die(mysql_error());
på produktionsmaskiner. Det finns händiga felhanteringsfunktioner i de flesta scriptspråk som snyggt och fint kan fånga in ett sådant databasfel och presentera en snygg sida ut mot användare istället för att kräkas upp ett felmeddelande med komplett fråga och sökvägar.

Weaver 2009-03-04 21:28

Om du ska använda MMC metod så se till att använda INSERT DELAYED och ha inga index på den tabellen så blir writes snabbare.

oloflolof 2009-03-04 21:54

Citat:

Originally posted by Weaver@Mar 4 2009, 21:28
Om du ska använda MMC metod så se till att använda INSERT DELAYED och ha inga index på den tabellen så blir writes snabbare.

Tycker du MMC förslag var bra Weaver eller har du några andra idéer på en bättre lösning?

Det med insert delayed verkar verkligen användbart sen när man får får mer besökare, det ska jag använda.

Citat:

och ha inga index på den tabellen
Läste lite på mysql hemsida men förstog inte riktigt vad index innebär. Skulle behöva en snabbguide där.


Jag tror du postade i fel tråd Magnus_A, Det verkar inte vara riktigt rätt info som jag är ute efter.


Citat:

Det du skrev med offlineuppdatering låter intressant.
Men en sak jag inte förstog. Du skrev att vid varje sidladdning kan man göra en INSERT. Skulle man inte innan kunna göra en COUNT och se om den redan finns, och om det inte fanns en post med unik_id och objekt_id göra en insert?
Eller blir det fortfarande mindre resurskrävande utan count och bara en insert vid varje?


MMC 2009-03-04 22:14

Citat:

Ursprungligen postat av oloflolof
Citat:

Ursprungligen postat av Weaver
Om du ska använda MMC metod så se till att använda INSERT DELAYED och ha inga index på den tabellen så blir writes snabbare.
Tycker du MMC förslag var bra Weaver eller har du några andra idéer på en bättre lösning?

Det med insert delayed verkar verkligen användbart sen när man får får mer besökare, det ska jag använda.
Citat:

och ha inga index på den tabellen

Läste lite på mysql hemsida men förstog inte riktigt vad index innebär. Skulle behöva en snabbguide där.

INSERT DELAYED är helt rätt att använda i den här situationen, ja. Vad gäller index så betyder det helt enkelt att du inte skapa några index (UNIQUE, INDEX, PRIMARY KEY osv) på tabellen du INSERTar till, eftersom varje index kräver beräkning från databasservern för varje ny rad som läggs till. Ha heller ingen auto_increment-kolumn.

Gör bara en INSERT och skippa kontroll för redan lagda röster/klick. Du är ute efter att få ner tiden och belastningen för en normal request så mycket som möjligt. Ditt cronskript är inte tidskänsligt på samma sätt och kan därför få göra grovjobbet.

oloflolof 2009-03-04 22:39

Citat:

Originally posted by MMC@Mar 4 2009, 22:14
text
Hej
Då fick jag en bra förklaring vad som menades med "index".

Har aldrig haft en tabell utan auto_increment innan så det kommer bli spännande att jobba med. :P

Tack för all hjälp hittills MMC, Weaver och Webbhelp. Kan tyvärr inte börja med detta förrens till helgen pga tidsbrist. Men jag kommer säkert att få mer funderingar och då fortsätter jag i denna tråden.


MVH Olof

Robert 2009-03-05 11:53

Varför inte köra updaten via ett ajaxanrop då dessa inte påverkas (körs igen) av sidrefresh?

oloflolof 2009-03-05 13:24

Citat:

Originally posted by Robert@Mar 5 2009, 11:53
Varför inte köra updaten via ett ajaxanrop då dessa inte påverkas (körs igen) av sidrefresh?
Men om man kör med javascript och ajax så kommre inte klick räknas på dom besökare som har javascript avaktiverat.
eller?

martine 2009-03-05 15:00

Citat:

Originally posted by oloflolof@Mar 5 2009, 14:24
Men om man kör med javascript och ajax så kommre inte klick räknas på dom besökare som har javascript avaktiverat.
För det första är det ju nuförtiden få som inte har js aktiverat och för det andra är det ju lätt gjort att få dessa via en nyladdning av sidan (via noscript eller någon annan mekanism).

oloflolof 2009-03-06 16:02

Citat:

Ursprungligen postat av martine
Citat:

Ursprungligen postat av oloflolof
Men om man kör med javascript och ajax så kommre inte klick räknas på dom besökare som har javascript avaktiverat.

För det första är det ju nuförtiden få som inte har js aktiverat och för det andra är det ju lätt gjort att få dessa via en nyladdning av sidan (via noscript eller någon annan mekanism).

Jo det är sant. Men jag tycker nog fortfarande förslaget innan låter bättre.
Men ajax är fortfarande ingen dålig lösning.

Är tacksam för alla förlsag! Kommer titta på det första nu. :)

oloflolof 2009-03-06 17:27

Hej igen, har kommit en bit på vägen och har en fråga.
Denna kod för jag på varje spel
Kod:

$sqlklick = "INSERT DELAYED INTO klick(unik_session_id,typ,typ_id)
 * * * * * *VALUES('".$unik_session_id ."', 'onlinespel', *'".$onlinespel[id]."')";
 * *mysql_query($sqlklick) or die(mysql_error());

Såhär ser min tabell ut
Citat:

unik_session_id * varchar(50) * latin1_swedish_ci * * * * * * *
typ *varchar(10) *latin1_swedish_ci *
typ_id *int(11) *

Såhär långt funkar allt bra och värderna kommer in i databasen.

Men det är nu i cron.php jag behöver hjälp och rådgivning
Jag vet faktiskt inte riktigt hur jag ska bygga upp denna biten på bäst sätt. Men om man börjar med något sånthär.


Kod:

$sql = mysql_query("SELECT * FROM klick WHERE typ = 'onlinespel'")or die(mysql_error());
while($klick = mysql_fetch_array($sql)) {
// Tittar om han skrev ut rätt, och det gjorde han
echo $klick[typ].": ".$klick[typ_id]." -----" .$klick[unik_session_id]."<br />";

Sen måste jag ju filtrera bort alla dubbletter innan jag kör en insert. Men jag vet faktiskt inte hur man gör en sådan.
Någon som har nån ide?

MVH Olof

oloflolof 2009-03-07 19:05

Har nu löst cron.php filen också Såhär blev det ifall någon kommer vilja ha samma lösning i framtiden.
Kod:

$sql = mysql_query("SELECT distinct *unik_session_id, typ_id, ip,typ FROM klick * ")or die(mysql_error());

while($klick = mysql_fetch_array($sql)) {
echo $klick[typ_id]." - - - - - " .$klick[unik_session_id]."--<br />";
$total_klick[$klick[typ_id]] = $total_klick[$klick[typ_id]] +1;

mysql_query("UPDATE ".$klick[typ]." SET klick=klick +1 WHERE id = ".$klick[typ_id]." ")or die(mysql_error());
if($klick[typ] == "onlinespel"){
mysql_query("UPDATE ".$klick[typ]." SET dagensklick=dagensklick +1 WHERE id = ".$klick[typ_id]." ")or die(mysql_error());
}
}
mysql_query("TRUNCATE TABLE klick");

Tack för allas hjälp!

MVH Olof


Alla tider är GMT +2. Klockan är nu 08:34.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson