Позвольте мне сразу начать с того, что я знаю, что это не лучшее решение. Я знаю, что это неуклюжее и хитрость. Но именно поэтому я здесь!
Этот вопрос / работа является результатом некоторого обсуждения Quora с Эндрю Босвортом , создатель новостной ленты Facebook.
Я создаю своего рода новостную ленту . Он построен исключительно на PHP
и MySQL
.
Реляционная модель для канала состоит из двух таблиц. Одна таблица функционирует как журнал активности; фактически он называется activity_log
. Другая таблица - это лента новостей
. Эти таблицы почти идентичны.
Схема для журнала - activity_log (uid INT (11), activity ENUM, activity_id INT (11), заголовок TEXT, дата TIMESTAMP)
... и схема для канала - это канал новостей (uid INT (11), poster_uid INT (11), activity ENUM, activity_id INT (11), заголовок TEXT, дата TIMESTAMP )
.
Каждый раз, когда пользователь делает что-то , имеющее отношение к ленте новостей, например, если задать вопрос, он будет немедленно занесен в журнал активности .
Затем каждые X минут (на данный момент 5 минут будет через 15-30 минут), Я запускаю задание cron , которое выполняет сценарий ниже. Этот сценарий просматривает всех пользователей в базе данных, находит все действия для всех друзей этого пользователя, а затем записывает эти действия в ленту новостей.
В настоящее время SQL
, который отбирает действие (вызываемое в ActivityLog :: getUsersActivity ()
) имеет LIMIT 100
, наложенный по причинам производительности *. * Не то чтобы я знаю, о чем говорю.
getAllUsers();
foreach($usersArray as $userArray) {
$uid = $userArray['uid'];
// Get the user's friends
$friendsJSON = $friend->getFriends($uid);
$friendsArray = json_decode($friendsJSON, true);
// Get the activity of each friend
foreach($friendsArray as $friendArray) {
$array = $activityLog->getUsersActivity($friendArray['fid2']);
// Only write if the user has activity
if(!empty($array)) {
// Add each piece of activity to the news feed
foreach($array as $news) {
$newsFeed->addNews($uid, $friendArray['fid2'], $news['activity'], $news['activity_id'], $news['title'], $news['time']);
}
}
}
}
В клиентском коде при загрузке ленты новостей пользователя я делаю что-то вроде:
$feedArray = $newsFeed->getUsersFeedWithLimitAndOffset($uid, 25, 0);
foreach($feedArray as $feedItem) {
// Use a switch to determine the activity type here, and display based on type
// e.g. User Name asked A Question
// where "A Question" == $feedItem['title'];
}
Прошу прощения за мое ограниченное представление о передовых методах разработки ленты новостей, но я понимаю, что применяемый мной подход является ограниченной версией того, что называется разветвлением при записи , ограниченный в том смысле, что я запускаю задание cron в качестве промежуточного шага вместо того, чтобы напрямую писать в новостные ленты пользователей. Но это сильно отличается от модели pull в том смысле, что новостная лента пользователя компилируется не под нагрузкой, а на регулярной основе.
Это большой вопрос, который, вероятно, заслуживает большого количества ответов. но я думаю, что это может служить пробным камнем для многих важных разговоров, которые необходимы новым разработчикам, таким как я. Я просто пытаюсь понять, что я делаю не так, как мне это исправить, или как мне, может быть, даже начать с нуля и попробовать другой подход.
Еще одна вещь, которая беспокоит меня в этой модели, - это то, что она работает на основе новизны, а не релевантности. Если кто-нибудь может предложить, как это можно улучшить для повышения актуальности, я буду всем вниманием. Я использую API Directed Edge для генерации рекомендаций, но мне кажется, что для чего-то вроде новостной ленты рекомендатели не работают (поскольку ранее ничего не было добавлено в избранное!).