[php/mysql] Forum berichten tellen: wat is beter?

Pagina: 1
Acties:

  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Ik ben zoals meer mensjes hier bezig met een eigen forum te bouwen. Ik ben nu bezig met het aantal berichten per thread/forum weer te geven. Nu zit ik te twijfelen tussen 2 methoden:
  • Gewoon elke keer als iemand een overzicht van threads of forums opvraagd een "SELECT COUNT* FROM blabla" uitvoeren.
  • In een appart veld voor elk(e) thread/forum bijhouden hoeveel posts er in staan. Elke keer als er gepost wordt worden deze variabelen bijgewerkt.
Minpunt van de eerste methode is snelheid. Stel dat er een overzicht wordt gegeven van 20 threads wordt gegeven moet er 20 keer een "SELECT COUNT*" worden uitgevoerd. Bij overzichten van de forums is dit zelfs nog erger, omdat er dan een JOIN verwerkt moet worden in de SELECT COUNT query. Bijv:
code:
1
2
3
4
SELECT COUNT(*) 
FROM messages, threads 
WHERE messages.thread_id = threads.thread_id
  AND threads.forum_id = $this_forumid

Daarom zou ik eigenlijk de tweede methode wel willen gebruiken, maar ik weet niet hoe het zit met locking enzo.
Stel dat ik de zaak zo implementeer dat als een user een bericht heeft gepost, het veld met het totaal aantal berichten middels een SELECT wordt opgehaald, en daarna met een UPDATE +1 wordt verhoogd.
Nu het probleem: Stel dat 2 users tegelijk een bericht posten, en heel toevallig tegelijk met een SELECT de waarde ophalen en daarna weer wegscrijven. Nu is de counter niet met 2 verhoogd, maar met 1. (Bijde users halen bijv. het getal 100 op en schrijven 101 weg).


Weet iemand mij te vertellen wat de beste methode is (misschien toch de 1e, maar dan wel argumenten plz) of hoe ik de tweede methode kan oplossen (semaphores ofzo :? )

Misschien kan Femme :9 of iemand anders die sleutelt aan het GOT forum mij vertellen hoe dat hier is gedaan????

Tnx in advance

Verwijderd

Op zondag 17 februari 2002 15:05 schreef metaal het volgende:
Nu het probleem: Stel dat 2 users tegelijk een bericht posten, en heel toevallig tegelijk met een SELECT de waarde ophalen en daarna weer wegscrijven. Nu is de counter niet met 2 verhoogd, maar met 1. (Bijde users halen bijv. het getal 100 op en schrijven 101 weg).
code:
1
UPDATE topics SET replies = replies + 1 WHERE topicid = 5
Weet iemand mij te vertellen wat de beste methode is (misschien toch de 1e, maar dan wel argumenten plz) of hoe ik de tweede methode kan oplossen (semaphores ofzo :? )
Ik gebruik de tweede
Misschien kan Femme :9 of iemand anders die sleutelt aan het GOT forum mij vertellen hoe dat hier is gedaan????
Femme sleutelt (helaas) niet aan dit forum en de meneren die dat wel doen zien we hier nooit meer (en sleutelen ook niet meer).

  • Erik Jan
  • Registratie: Juni 1999
  • Niet online

Erik Jan

Langzaam en zeker

Hmm, in dit geval zou ik gewoon UPDATE x SET y=y+1 doen... Die SELECT is dus overbodig.

/te laat

This can no longer be ignored.


  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Ow, nouw das simpeler dan ik dacht |:( Met die update loop ik dus geen risico op dat ene probleem dat ik boven bescreef?

Verwijderd

Op zondag 17 februari 2002 15:12 schreef metaal het volgende:
Ow, nouw das simpeler dan ik dacht |:( Met die update loop ik dus geen risico op dat ene probleem dat ik boven bescreef?
Nee

  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Tnx, was een snel antwoord :)

  • Erik Jan
  • Registratie: Juni 1999
  • Niet online

Erik Jan

Langzaam en zeker

Zie http://www.mysql.com/doc/T/a/Table_locking.html
MySQL uses table locking (instead of row locking or column locking) on all table types, except InnoDB and BDB tables, to achieve a very high lock speed. For large tables, table locking is much better than row locking for most applications, but there are, of course, some pitfalls.
[...]
Table locking enables many threads to read from a table at the same time, but if a thread wants to write to a table, it must first get exclusive access. During the update, all other threads that want to access this particular table will wait until the update is ready.
Je kan het dus zien als een soort queue waarbij alle updates en inserts enzo 1 voor 1 worden afgewerkt.

This can no longer be ignored.


  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Oops, staat gewoon in de docs. Misschien moet ik eens wat minder snel ergens overheen te lezen

* metaal begint zich een beetje dom te voelen

Verwijderd

Op zondag 17 februari 2002 15:19 schreef metaal het volgende:
Oops, staat gewoon in de docs. Misschien moet ik eens wat minder snel ergens overheen te lezen

* metaal begint zich een beetje dom te voelen
staal leeft

Verwijderd

In plaats van +1 zou ik gewoon een COUNT* doen. Echter niet iedere keer bij het laten zien maar gewoon het veldje updaten na een post of delete.
Op die manier weet je tenminste zeker dat hij goed staat.

  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
Op zondag 17 februari 2002 16:28 schreef MarcoTC het volgende:
In plaats van +1 zou ik gewoon een COUNT* doen. Echter niet iedere keer bij het laten zien maar gewoon het veldje updaten na een post of delete.
Op die manier weet je tenminste zeker dat hij goed staat.
Ja, kan je doen, maar het wordt wel een stuk trager.

Je zou bijvoorbeeld ook een admin-knopje kunnen maken dat deze waarde even update.

edit: maar dan moet je normaal wel even een update doen natuurlijk, het knopje is alleen voor noodgevallen uiteraard :)

  • elnino
  • Registratie: Augustus 2001
  • Laatst online: 03-09 05:13
Op zondag 17 februari 2002 15:05 schreef metaal het volgende:
Nu het probleem: Stel dat 2 users tegelijk een bericht posten, en heel toevallig tegelijk met een SELECT de waarde ophalen en daarna weer wegscrijven. Nu is de counter niet met 2 verhoogd, maar met 1. (Bijde users halen bijv. het getal 100 op en schrijven 101 weg).
Zo'n kans is ontzettend klein. MySQL doet zo'n query in een honderdste van een seconde ongeveer. En dat er dan precies twee mensen op dezelfde tijd het doen is dus (bijna) te verwaarlozen. Daarnaast is de manier van PlayR brammetje ook een handige om het bij te 'vijlen'.

  • Jorn
  • Registratie: Juni 2001
  • Laatst online: 13-09 12:30
Als je zoiets zou willen van: op dit moment telt dit vorum X berichten en Y reply's,
Dan zou ik dit b.v. elke 10 minuten met een cronjob in een bestand laten zetten, moet je server natuurlijk wel cron-jobs ondersteunen:p

* Erkens is een sukkel en ramt in mirc op f5 :+
* XTerm GROOOOOOTE kuis houden op hd's :)


Verwijderd

Ik maak gebruik van een apart veld, dat is voor je MySQL deamon veer liever en als je bang bent dat er een verschil kan ontstaan kan je bijvoorbeeld eens per week via een update scriptje al je users met hun posts synchroniseren.

  • elnino
  • Registratie: Augustus 2001
  • Laatst online: 03-09 05:13
Op zondag 17 februari 2002 19:55 schreef j_iscool het volgende:
Als je zoiets zou willen van: op dit moment telt dit vorum X berichten en Y reply's,
Dan zou ik dit b.v. elke 10 minuten met een cronjob in een bestand laten zetten, moet je server natuurlijk wel cron-jobs ondersteunen :P
Cron-jobs zijn hiervoor wel een beetje overdreven... De statistieken kloppen niet (er kunnen in die 10 minuten weer nieuwe bijkomen) en een apart veld dat alleen geupdate wordt bij een nieuwe post van een user is veel handiger. Bovendien moet je bij een cron-job het ook ergens in opslaan.

En zoals je zelf al zegt, niet iedereen heeft de mogelijkheid om van cron-jobs gebruik te maken, helaas.

Verwijderd

as far as i can see gebruikt VBulletin ( een heel veel gebruikt commercieel Bulletin Bord dat draait op PHP en MySQL, die heeeeeel toevallig op mn HD kwam ) gewoon counts hiervoor. en dat kan mysql heel goed aan. Vergeet niet dat mysql in principe de snelste database is die er bestaat.
ik denk dat je je pas zorgen moet gaan maken op het moment dat je een goede 100.000 bezoekers per dag krijgt
(gokje, voor dit bord gebruiken ze dezelfde manier)

  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Ik denk dat ik toch maar de tweede ga gebruiken. Ik was vooral bang dat twee users een fout zouden veroorzaken met het verhogen, maar dat probleem vervalt als ik de updates gebruik.

De enige manier waardoor de telling door de war geschopt kan worden is denk ik een programmeer fout (niet na elke post de counter refreshen).
Ik heb inmiddels al een scriptje geschreven die hier op controleert. Deze kan ik gewoon elke nacht om 04:00 laten draaien en als er fouten zijn stuurtie gewoon een mailtje. In dat mailtje zit een hyperlink naar een scriptje dat de boel weer goedzet *D

Ik zie af van COUNT* omdat het boardje op een servertje gaat draaien die ook door andere users gebruikt wordt voor andere doeleinden, zoals downloaden met reetehoge snelheden. (Helaas, tis de enige gratis dedicated server met alle mogelijkheden zoals cron die ik kan vinden)

Btw, al zou het forum op een snelle bak draaien, COUNT* blijft toch langzamer denk ik. Er moet namelijk een join worden uitgevoerd om het aantal berichten per forum te bepalen (zo zit mn database ontwerp in elkaar, die wil ik niet veranderen)

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Als je voor de tweede optie gaat (welke ik ook aan zou raden) let dan wel op het moven van topics en het deleten van posts en topics.

Who is John Galt?


  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Op zondag 17 februari 2002 22:37 schreef justmental het volgende:
Als je voor de tweede optie gaat (welke ik ook aan zou raden) let dan wel op het moven van topics en het deleten van posts en topics.
had ik idd nog niet aan gedacht. Ik denk dat ik nog wel wat meer gevalletjes over het hoofd zal zien, maar daar heb ik dus dat scriptje voor.

Verwijderd

sou, je hebt je keuze dus al gemaakt :)

maak even een scriptje die dagelijks/wekelijks/maandelijks/jaarlijks of manual de post/thread count uit de DB berekent (count dus) en even het veld weer goedzet... je zal mischien met veel gebruikers af en toe de posts wel es willen deleten denk ik :)

  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Op zondag 17 februari 2002 22:42 schreef TheViP het volgende:
maak even een scriptje die dagelijks/wekelijks/maandelijks/jaarlijks of manual de post/thread count uit de DB berekent (count dus) en even het veld weer goedzet... je zal mischien met veel gebruikers af en toe de posts wel es willen deleten denk ik :)
Dat is dat scriptje waar ik het over had. Crond moet em starten (4:00 's nachts ofzow), en ik krijg een iemeel als het fout is.

  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
Op zondag 17 februari 2002 22:42 schreef TheViP het volgende:
je zal mischien met veel gebruikers af en toe de posts wel es willen deleten denk ik :)
mwoh, daar hou je dan toch gewoon rekening mee? lijkt het je niet handiger om dan je count gewoon te updaten? :P

Verwijderd

wat ik zou doen is elke keer als er een nieuwe post is gewoon de
UPDATE x SET y=y+1
query uitvoeren en dan om 12 uur 's nachts een cronjob uitvoeren om te controleren of de statistieken nog wel kloppen en ze zonodig bijwerken. Zo heb je (mijn mening) de snelste manier voor de client (een select ipv een count) en je statistieken kloppen toch altijd (bijna altijd, als het een keer fout gaat, wat eens in de 5 maanden misschien gebeurt wordt het om 12 uur 's nachts weer recht gebreid...)

  • metaal
  • Registratie: Juli 2001
  • Laatst online: 31-01-2025
Op maandag 18 februari 2002 12:27 schreef jurriebur het volgende:
(bijna altijd, als het een keer fout gaat, wat eens in de 5 maanden misschien gebeurt wordt het om 12 uur 's nachts weer recht gebreid...)
Ik denk dat als de code waterdicht is, de fout zelfs helemaal niet hoeft op te treden.

Trouwens, als ik het "correctie-scriptje" uitvoer moet ik denk ik wel ff het forum op read-only zetten, om te voorkomen dat iemand tijdens het updaten een bericht post.
Pagina: 1