Frage

Auf einer PHP & CodeIgniter-basierte Web-Site kann Benutzer Ruf für verschiedene Aktionen verdient, nicht anders als Stack-Überlauf. Jedes Mal Ruf wird vergeben, wird ein neuer Eintrag in einer Tabelle mit dem MySQL user_id erstellt, Aktion belohnt, und den Wert dieses Bündel von Punkten (beispielsweise 10 Ruf). Zur gleichen Zeit, ein Feld in einer Tabelle users, reputation_total, aktualisiert wird.

Da alle diese Art von sinnlos ohne Referenzrahmen ist, möchte ich Benutzer unter allen Benutzern, ihre Perzentilrang zeigen. Für die totalen Ruf, scheint einfach genug. Lassen Sie uns sagen, dass meine user_id 1138 ist. Zählen Sie die Anzahl der Benutzer in der users Tabelle mit einem reputation_total weniger als meinte, die Gesamtzahl der Benutzer zählen und teilt den Prozentsatz der Nutzer mit einem niedrigen Ruf als meine zu finden. Das wird Benutzer 1138 den Prozentrang, nicht wahr? Easy!

Aber ich bin Anzeige auch Ruf Summen über verschiedene Zeitspannen - z. B. verdiente in den letzten sieben Tagen, die den Ruf Tabelle beinhaltet die Abfrage und Summieren alle meine Punkte seit einem bestimmten Zeitpunkt erworben. Ich würde auch Perzentilrang zeigen, wie für die verschiedenen Zeitspannen - z. B. kann ich insgesamt 11. Perzentil, aber 50. Perzentil in diesem Monat und der 97. Perzentile heute.

Es scheint, muss ich durch gehen würde und die Reputation Summen aller Nutzer für den angegebenen Zeitraum zu finden, und dann sehen, wo ich innerhalb dieser Gruppe fallen, nicht wahr? Ist das nicht furchtbar umständlich? Was ist der beste Weg, dies zu tun?

Vielen Dank.

War es hilfreich?

Lösung

kann ich denke an ein paar Optionen aus der Spitze von meinem Kopf hier:

  1. Wie Sie erwähnt haben, die Rating-Punkte insgesamt bis während der Zeitbereich verdient und berechnen Reihen der Perzentile auf der Grundlage dieser.

  2. Track-Updates auf einer täglichen Basis reputation_total - so haben Sie eine Tabelle mit user_id, Datum, reputation_total

  3. .
  4. Fügen Sie einige neue Spalten in der Benutzertabelle (reputation_total, reputation_total_today, reputation_total_last30days, etc.) für jeden Zeitbereich. Sie können auch diese in einer separaten Tabelle (reputation_totals) normalisieren Sie verhindern, dass eine neue Spalte für jede Zeitspanne hinzufügen, die Sie verfolgen möchten.

Option 1 ist die einfachste, aber es ist wahrscheinlich langsam in Gang zu bringen, wenn Sie viele Zeilen in Ihrer Ruf Transaktionstabelle haben - es ist nicht sehr gut skalieren, vor allem, wenn Sie diese in Echtzeit berechnen müssen.

Option # 2 wird mehr Speicher im Laufe der Zeit benötigen (eine Zeile pro Benutzer pro Tag), aber wahrscheinlich wesentlich schneller wäre als direkt die Transaktionstabelle abgefragt wird.

Option # 3 ist weniger flexibel, würde aber wahrscheinlich die schnellste Option sein.

Die beiden Optionen 2 und 3 erfordern würde wahrscheinlich einen Batch-Prozess die Summen auf einer täglichen Basis zu berechnen, so dass etwas als gut zu betrachten.

Ich glaube nicht eine Option ist unbedingt die beste - sie alle unterschiedliche Vor- und Nachteile der Geschwindigkeit / Stauraum / Komplexität / Flexibilität beinhalten. Was Sie tun, hängt letztlich von den Anforderungen für Ihre Anwendung natürlich.

Andere Tipps

Ich sehe nicht, warum das auch wäre zu komplex. Generell sind alle müssen Sie zu Ihrer WHERE-Klausel eine Abfrage hinzuzufügen, die Ergebnisse wie begrenzt:

WHERE DatePosted between @StartOfRange and @EndOfRange
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top