2009-06-04 19 views
6

Próbuję zaprogramować wtyczkę do bbPress (oprogramowanie forum open source), które będzie działać podobnie do Hacker News (http://news.ycombinator.com/).Jak sortować jak wiadomości hakerskie

szczególności chcę uporządkować kolejność forum-Nitki (bbPress nazywa je „tematów”) za pomocą następującego algorytmu:

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 

chciałbym móc sortować posty tego obliczone sort_value korzystania MySQL.

odpowiednie pola w tabeli topics wygląda mniej więcej tak:

topic_id   bigint(20) 
topic_start_time datetime 

To jest w powietrzu, ale myślałem, że będzie kolejna tabela przechowująca pojedynczych głosów przez użytkowników tak będziemy wiedzieć, czy użytkownik już głosował. Kolejna tabela będzie przechowywać bieżące liczby głosów dla każdego tematu. Może w tym stole pojawi się inne pole przechowujące najnowszą obliczoną wartość sort_Value?

Aby być w 100% dokładnym, wartość sort_na powinna być aktualizowana po każdym nowym głosowaniu w. To jednak spowodowałoby zbyt duże obciążenie serwera bazy danych, szczególnie jeśli staraliśmy się zaktualizować WSZYSTKIE tematy. Jeśli będziemy musieli, możemy ograniczyć zbiór danych, obliczając tylko wartość sort_ dla ostatnich X # tematów. Możemy również ograniczyć obciążenie, okresowo aktualizując wartość sort_a (np. Co 5 minut za pomocą zadania cron).

Skróty te mogą sprawić, że obciążenie będzie do przyjęcia, ale wolę bardziej eleganckie rozwiązanie, które można skalować lepiej.

Jak byście to ukształtowali? :-)

Odpowiedz

0

OK, to jest mój pomysł. Zacznę od utworzenia old_table, który ma X wiersze tematów z polem sort_value.

Chcę uniknąć ton instrukcji UPDATE na jednym stole, więc okresowo zastępuję starą tabelę świeżo obliczoną tabelą. O ile mi wiadomo, MySQL nie obsługuje składni "zamień tabelę", więc co Y minut, za pośrednictwem crona, utworzę zaktualizowaną wersję tej tabeli o nazwie new_sort_value. Potem zrobię tej sekwencji poleceń:

  • DROP old_table
  • RENAME new_table do old_table

Czy to wydawać się ważnej podejście?

+0

Uważam, że jest to ważne, jeśli jest trochę niezgrabne. Niestety, masz do czynienia z ograniczeniami systemu, do którego dodajesz. Skalowanie tego rodzaju problemów jest dokładnie takie, o czym nie radzą sobie bazy danych rdbms. Coś jak widok CouchDB będzie tą samą uliczką. –

+0

Dzięki, Jeremy. Sprawdzę CouchDB. Właśnie pomyślałem o kolejnym ulepszeniu tego pomysłu, który polega na zapisaniu (gdzie indziej) wartości określającej, która "tabela" jest aktywna. Powiedzmy, że bieżąca wartość to 'old_table'. Dzięki temu moja aplikacja wykona polecenie JOIN względem 'old_table'. Następnie, po utworzeniu zaktualizowanej 'new_table', zaktualizowałbym wartość" Aktywnej bazy danych "do" nowej_tabeli ". Pozwoli to uniknąć DROP tabeli żądanej dla zwykłych JOINów. – bobbyh

1

Istnieje kilka powodów do rozważenia. Wspomniałeś już o nich w swoim pytaniu. Terminowość i dokładność w porównaniu do obciążenia i skali.

Wiązanie obliczeń jest najlepszym sposobem zmniejszenia obciążenia i zwiększenia skali, jeśli nie jest konieczna dokładność i dokładność, a system doświadcza dużego obciążenia podczas zapisywania.

Naprawdę musisz przeanalizować wykorzystanie systemu i określić, jakie obszary potrzebujesz do optymalizacji. Optymalizacja dla zapisu ma różne ograniczenia niż optymalizacja dla Odczytów. To samo dotyczy aktualności lub dokładności danych.

Określ, które z nich są najważniejsze dla Twojego zastosowania i dokonaj odpowiedniego kompromisu.