Как сортировать как хакерские новости
Я пытаюсь запрограммировать плагин для bbPress (программное обеспечение форума с открытым исходным кодом), который будет работать аналогично Hacker News ( http://news.ycombinator.com/).
В частности, я хочу отсортировать порядок разделов форума (bbPress называет их "темами"), используя следующий алгоритм:
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
Я хотел бы иметь возможность сортировать темы по этому вычисленному sort_value, используя MySQL.
Соответствующие поля в topics
таблица выглядит примерно так:
topic_id bigint(20)
topic_start_time datetime
Это в воздухе, но я думал, что будет еще одна таблица, в которой будут храниться отдельные голоса пользователей, поэтому мы сможем узнать, проголосовал ли пользователь уже. А в другой таблице будут храниться текущие итоги голосования по каждой теме. Может быть, в этой таблице будет еще одно поле, в котором будет храниться последнее вычисленное значение sort_Value?
Чтобы быть на 100% точным, значение sort_value должно обновляться после каждого нового голосования. Однако это добавит слишком много нагрузки на сервер базы данных, особенно если мы попытаемся обновить ВСЕ темы. Если нам нужно, мы могли бы ограничить набор данных, только вычисляя sort_value для последних X # тем. Мы также можем ограничить загрузку, только периодически обновляя sort_value (например, каждые 5 минут с помощью задания cron).
Эти сочетания клавиш могут сделать нагрузку приемлемой, но я бы предпочел более элегантное решение, которое могло бы масштабироваться лучше.
Как бы вы это структурировали?:-)
2 ответа
ОК, это моя идея. Я начну с создания old_table
у которого есть X строк тем с полем sort_value.
Я хочу избежать множества операторов UPDATE для одной таблицы, поэтому я буду периодически заменять старую таблицу на только что вычисленную. Насколько мне известно, MySQL не поддерживает синтаксис "заменить таблицу", поэтому каждые Y минут через cron я буду создавать обновленную версию этой таблицы под названием new_sort_value
, Тогда я сделаю эту последовательность команд:
- DROP
old_table
- ПЕРЕИМЕНОВАТЬ
new_table
вold_table
Это похоже на правильный подход?
В этом есть несколько компромиссов. Вы намекали на них уже в своем вопросе. Своевременность и точность против нагрузки и масштаба.
Пакетные вычисления - лучший способ уменьшить Load и увеличить Scale, если Своевременность и Точность не требуются, и система испытывает большое количество записей.
Вы действительно должны как-то изучить использование системы и определить, для каких областей вам нужно оптимизировать. Оптимизация для записи имеет другие ограничения, чем оптимизация для чтения. То же самое для своевременности или точности данных.
Определите, какие из них наиболее важны для вашего приложения, и сделайте соответствующий компромисс.