2009-06-04 1 views
6

Ich versuche, ein Plugin zu bbPress (die Open-Source-Forum-Software) zu programmieren, die ähnlich wie Hacker News (http://news.ycombinator.com/) funktionieren wird.So sortieren Sie wie Hacker News

Insbesondere möchte ich die Reihenfolge der Forum-Threads sortieren (bbPress nennt sie „Themen“) mit dem folgenden Algorithmus:

sort_value = (p - 1)/(t + 2)^1.5 
where p = total votes for each topic from users 
t = time since submission of each topic in hours 

Ich möchte in der Lage sein, Themen zu sortieren, indem dieser berechnete sort_value mit MySQL.

Die entsprechenden Felder in der topics Tabelle sieht wie folgt aus etwas:

topic_id   bigint(20) 
topic_start_time datetime 

Dies ist in der Luft, aber ich dachte, es wird eine weitere Tabelle, die von den Benutzern individuelle Stimmen speichert, so werden wir sein kann wissen, ob ein Benutzer bereits gewählt hat. Und eine weitere Tabelle speichert die aktuellen Stimmen für jedes Thema. Vielleicht wird es ein anderes Feld in dieser Tabelle geben, in dem der letzte berechnete sort_Value gespeichert wird?

Um 100% genau zu sein, sollte der sort_value nach jeweils neue Abstimmung aktualisiert werden. Dies würde dem Datenbankserver jedoch zu viel Last hinzufügen, insbesondere wenn wir versuchen, ALLE Themen zu aktualisieren. Wenn wir müssen, können wir den Datensatz begrenzen, indem wir nur den sort_value für die letzten X # -Themen berechnen. Wir könnten die Last auch begrenzen, indem wir den sort_value nur periodisch aktualisieren (z. B. alle 5 Minuten über einen Cron-Job).

Diese Abkürzungen könnten die Belastung akzeptabel machen, aber ich würde eine elegantere Lösung bevorzugen, die besser skaliert werden könnte.

Wie würden Sie das strukturieren? :-)

Antwort

0

OK, das ist meine Idee. Ich beginne mit der Erstellung einer old_table, die X Zeilen von Themen mit einem Feld sort_value hat.

Ich möchte Tonnen von UPDATE-Anweisungen auf einer einzigen Tabelle vermeiden, also werde ich die alte Tabelle regelmäßig durch eine frisch berechnete Tabelle ersetzen. Soweit mir bekannt ist, unterstützt MySQL keine "replace table" -Syntax. Daher erstelle ich alle fünf Minuten über cron eine aktualisierte Version dieser Tabelle namens new_sort_value. Dann werde ich diese Folge von Befehlen tun:

  • DROP old_table
  • RENAME new_table zu old_table

dies wie ein brauchbares Konzept scheint?

+0

Ich denke, das ist gültig, wenn ein wenig ungeschickt. Leider haben Sie es mit den Einschränkungen des Systems zu tun, das Sie hinzufügen. Skalierung dieser Art von Problem ist genau das, was rdbms-Datenbanken nicht gut machen. So etwas wie eine CouchDB-Ansicht wäre genau diese Gasse. –

+0

Danke, Jeremy. Ich checke CouchDB aus. Ich dachte gerade an eine andere Optimierung dieser Idee, nämlich nur einen Wert zu speichern, der besagt, welche 'Tabelle' aktiv ist. Angenommen, der aktuelle Wert ist 'old_table'. Das würde meiner App sagen, dass sie JOIN gegen 'old_table' machen soll. Dann, nach dem Erstellen einer aktualisierten 'new_table', würde ich den Wert" Aktive Datenbank "auf" neue_tabelle "aktualisieren. Dies würde eine DROP einer Tabelle vermeiden, die für reguläre JOINs angefordert wird. – bobbyh

1

Es gibt eine Reihe von Kompromissen, die dabei berücksichtigt werden müssen. Du hast sie schon in deiner Frage angedeutet. Aktualität und Genauigkeit gegenüber Last und Maßstab.

Das Stapeln der Berechnungen ist der beste Weg, die Auslastung zu verringern und die Skalierung zu erhöhen, wenn Aktualität und Genauigkeit nicht erforderlich sind und das System eine hohe Schreiblast hat.

Sie müssen wirklich die Verwendung des Systems untersuchen und bestimmen, für welche Bereiche Sie optimieren müssen. Die Optimierung für Write hat andere Einschränkungen als die Optimierung für Lesevorgänge. Gleiches gilt für Aktualität oder Exaktheit der Daten.

Bestimmen Sie, welche für Ihre Anwendung am wichtigsten sind, und treffen Sie den entsprechenden Kompromiss.