2009-06-04 11 views
6

Sto provando a programmare un plugin per bbPress (il software del forum open source) che funzionerà in modo simile a Hacker News (http://news.ycombinator.com/).Come ordinare come Hacker News

In particolare, voglio ordinare l'ordine del forum-thread (bbPress li chiama "temi") utilizzando il seguente algoritmo:

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 

Vorrei essere in grado di ordinare i messaggi di questo calcolati sort_value utilizzando MySQL.

I campi rilevanti della tabella topics sembra qualcosa di simile:

topic_id   bigint(20) 
topic_start_time datetime 

Questo è in aria, ma stavo pensando ci sarà un altro tavolo che memorizza i singoli voti dagli utenti così saremo in grado di sapere se un utente ha già votato. E un'altra tabella memorizzerà gli attuali voti-totali per ogni argomento. Forse ci sarà un altro campo in quella tabella che memorizza l'ultimo sort_Valore calcolato?

Per essere accurato al 100%, il sort_value deve essere aggiornato dopo ogni nuova votazione. Ciò aggiungerebbe troppo carico al server del database, specialmente se tentassimo di aggiornare TUTTI gli argomenti. Se necessario, potremmo limitare il set di dati calcolando solo il valore sort per l'ultimo X # di argomenti. Potremmo anche limitare il carico aggiornando periodicamente il valore sort_ (ad es. Ogni 5 minuti tramite un cron job).

Queste scorciatoie potrebbero rendere accettabile il carico, ma preferirei una soluzione più elegante che potesse scalare meglio.

Come lo strutturate? :-)

risposta

0

OK, questa è la mia idea. Inizierò creando uno old_table con X righe di argomenti con un campo sort_value.

Voglio evitare tonnellate di istruzioni UPDATE su una singola tabella, quindi sostituirò periodicamente la vecchia tabella con una tabella appena calcolata. Per quanto ne so, MySQL non supporta la sintassi "replace table", quindi ogni Y minuti, tramite cron, creerò una versione aggiornata di questa tabella chiamata new_sort_value. Poi farò questa sequenza di comandi:

  • GOCCIA old_table
  • RENAME new_table al old_table

Questo sembra come un valido approccio?

+0

Penso che sia valido se un po 'goffo. Sfortunatamente hai a che fare con i vincoli del sistema che stai aggiungendo. Scalare questo tipo di problema è esattamente il tipo di cosa che i database rdbms non fanno bene a. Qualcosa come una vista CouchDB sarebbe proprio in questo vicolo. –

+0

Grazie, Jeremy. Controllerò CouchDB. Ho appena pensato a un altro tweak a questa idea, che è quello di salvare (altrove) un valore che dice quale 'table' è attiva. Dì che il valore corrente è 'old_table'. Questo direbbe alla mia app di fare un JOIN contro 'old_table'. Quindi, dopo aver creato un 'new_table' aggiornato, avrei UPDATE il valore di" Database attivo "a' new_table'. Ciò eviterebbe un DROP di una tabella che viene richiesta per regolari JOIN. – bobbyh

1

Ci sono un certo numero di compromessi da considerare in questo. Li hai già accennati nella tua domanda. Tempestività ed Esattezza vs Carico e scala.

Il raggruppamento dei calcoli è il modo migliore per ridurre Carico e aumentare la scala se Tempestività ed Esattezza non sono necessarie e il sistema subisce un carico elevato di scritture.

Devi davvero esaminare l'utilizzo del sistema e determinare quali aree devi ottimizzare. L'ottimizzazione per la scrittura presenta diversi vincoli rispetto all'ottimizzazione per le letture. Lo stesso per la tempestività o l'esattezza dei dati.

Determina quali sono più importanti per la tua applicazione e fai il compromesso appropriato.