[MySQL] Voting systeem, met random record op basis van score

Pagina: 1
Acties:

  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 25-11-2025
Hallo!

Ik heb in MySQL 5.0 een table met quotes (beetje zoals bash) met daarin een 'score' veld. Wanneer een bezoeker op een quote vote, wordt de score +1 of -1.

Nu heb ik een SELECT statement met ORDER BY rand() LIMIT 1 om bij binnenkomst een random quote te laten zien.

Om nu te zorgen dat een quote met een hogere score vaker voorkomt, zou ik dus een record met score 5 ook 5 keer moeten selecteren (in een subquery) om er vervolgens random 1 uit te halen. Hoe zou ik dit voor elkaar kunnen krijgen met enkel MySQL ?

Bedankt voor de hulp

  • CrashOne
  • Registratie: Juli 2000
  • Niet online

CrashOne

oOoOoOoOoOoOoOoOoOo

Als je er nu meer selecteerd en dan een ORDER BY score DESC doet?

Huur mij in als freelance SEO consultant!


Verwijderd

Is het niet een stuk makkelijker om twee tabellen te nemen:
eentje met een ID en een Quote
eentje met een eigen PK en een FK naar quotes

Dan ipv "+1" te doen, gewoon een keer extra inserten in de tweede tabel.
Bij deleten haal je er een weg uit tweede tabel (zo 1 2 3 geen idee hoe je dat netjes moet doen, though :))
Dan kun je gewoon randommen op de tweede tabel, en de quote uit de eerste tabel halen.

  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 25-11-2025
CrashOne schreef op woensdag 26 april 2006 @ 22:11:
Als je er nu meer selecteerd en dan een ORDER BY score DESC doet?
Hoe selecteer ik er meer... Ik moet dus een record een x aantal keren selecteren, op basis van het score veld in datzelfde record..

Order by ed maakt niet uit.. het gaat er om dat 1 record meerdere keer geselecteerd wordt, zodat de kans groter wordt dat de random hem pakt.
Verwijderd schreef op woensdag 26 april 2006 @ 22:16:
Is het niet een stuk makkelijker om twee tabellen te nemen:
eentje met een ID en een Quote
eentje met een eigen PK en een FK naar quotes

Dan ipv "+1" te doen, gewoon een keer extra inserten in de tweede tabel.
Bij deleten haal je er een weg uit tweede tabel (zo 1 2 3 geen idee hoe je dat netjes moet doen, though :))
Dan kun je gewoon randommen op de tweede tabel, en de quote uit de eerste tabel halen.
Die 2e table kan wel flink uit de hand lopen dan.. en ik zit even met het punt.. wat als een quote op 0 staat.. en een user vote - ??

wat ik had bedacht is.. pak de MIN value (bijvoorbeeld -120) en zet dat om in een positief nummer (120).. tel er 1 bij op (121) en tel dat bij de score op.. zo wordt dus de laagste score 1 en de rest wordt ook hoger..

Maarja.. dan nog ff dat record x aantal keren selecteren

[ Voor 76% gewijzigd door Mephix op 26-04-2006 22:19 ]


  • Japidoff
  • Registratie: November 2001
  • Laatst online: 16-01 18:20
Mephix schreef op woensdag 26 april 2006 @ 22:16:
[...]


Die 2e table kan wel flink uit de hand lopen dan.. en ik zit even met het punt.. wat als een quote op 0 staat.. en een user vote - ??
echt "groot" zal hij niet worden, met bijv. een INT vote_id en een INT score?
je zou die table een MEMORY kunnen maken voor de snelheid, maar t lijkt mij toch een btje zot om die table elke hit opnieuw te maken...
wat ik had bedacht is.. pak de MIN value (bijvoorbeeld -120) en zet dat om in een positief nummer (120).. tel er 1 bij op (121) en tel dat bij de score op.. zo wordt dus de laagste score 1 en de rest wordt ook hoger..

Maarja.. dan nog ff dat record x aantal keren selecteren
ik denk toch dat je een while lus zult moeten gebruiken, in php of mysql..

gang is alles


  • Mephix
  • Registratie: Augustus 2001
  • Laatst online: 25-11-2025
Ja, met een while lus moet het sowieso lukken..

Als alternatief had ik: maak een array aan, met alle quote_id's erin (afhankelijk van de score komt een quote_id dan meerdere keren voor in die array).. en pak vervolgens een random array veld eruit.. dat wordt dan je random quote...

Niet zo netjes natuurlijk en misschien ook nog wel behoorlijk traag, maarja..

  • ZroBioNe
  • Registratie: Augustus 2001
  • Niet online
Japidoff schreef op donderdag 27 april 2006 @ 07:29:
[...]

echt "groot" zal hij niet worden, met bijv. een INT vote_id en een INT score?
je zou die table een MEMORY kunnen maken voor de snelheid, maar t lijkt mij toch een btje zot om die table elke hit opnieuw te maken....
Bij bash.org hebben sommige quotes meer dan 10000 punten als score.
Je zou zo ie zo niet handig bezig zijn, want stel dat 1000 users +1 voten, dan weer 30 users -1, en weer 50 +1, heb je een score van 1020, maar wel 1080 records.
Als er nog meer votes komen, gaat dit uit de hand lopen..

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
De 1e hit op Google op 'sql weighted random query' gaf deze query:
SELECT *
FROM `Quotes`
WHERE score != 0 ORDER BY Rand()*(1/score) LIMIT 1

Deze aanpak laat al een nieuwe denkwijze zien: de uitkomst van de random functie aanpassen al naar gelang de row zelf. Een andere optie is om een random minimum score te vereisen in de WHERE clause.
Uiteraard kan je ook de where weglaten en ORDER BY Rand()*(1/score+1) doen als je wel records met score 0 wil kunnen selecteren en toch delen door 0 wil voorkomen. :)

{signature}


  • Japidoff
  • Registratie: November 2001
  • Laatst online: 16-01 18:20
SELECT *, (Rand()*(1/(score+1+(SELECT ABS(MIN(score)) FROM tips)))) AS calc
FROM `tips`
WHERE 1 ORDER BY calc LIMIT 1

dit is m,
deze werkt dus ook met negatieve scores..

gang is alles

Pagina: 1