Дозвольте мені розпочати відразу, сказавши, що я знаю, що це не найкраще рішення. Я знаю, що це студійно і хак функції. Але тому я тут!
Це питання / робота побудовано на деякій дискусії щодо Quora з Ендрю Босвортом , творцем стрічки новин Facebook.
Я будую своєрідну стрічку новин . Він вбудований виключно в PHP
і MySQL
.
MySQL
Реляційна модель корму складається з двох таблиць. Одна таблиця функціонує як журнал активності; насправді це названо activity_log
. Інша таблиця newsfeed
. Ці таблиці майже однакові.
Схема для журналу єactivity_log(uid INT(11), activity ENUM, activity_id INT(11), title TEXT, date TIMESTAMP)
... а схема подачі така newsfeed(uid INT(11), poster_uid INT(11), activity ENUM, activity_id INT(11), title TEXT, date TIMESTAMP)
.
Щоразу, коли користувач робить щось, що стосується стрічки новин, наприклад, задаючи питання, він негайно потрапляє до журналу активності .
Створення стрічок новин
Потім кожні X хвилин (на даний момент 5 хвилин, і це зміниться на 15-30 хвилин пізніше), я запускаю роботу cron, яка виконує сценарій нижче. Цей сценарій циклічно переглядає всіх користувачів у базі даних, знаходить усі дії для всіх друзів цього користувача, а потім записує ці дії у стрічку новин.
На даний момент те, SQL
що відбирає діяльність (викликане ActivityLog::getUsersActivity()
), LIMIT 100
накладається з причин * результативності. * Не те, щоб я знав, про що кажу.
<?php
$user = new User();
$activityLog = new ActivityLog();
$friend = new Friend();
$newsFeed = new NewsFeed();
// Get all the users
$usersArray = $user->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 як проміжний крок замість того, щоб писати безпосередньо в стрічки новин користувачів. Але це сильно відрізняється від моделі витягування, в тому сенсі, що стрічка новин користувача складається не на завантаженні, а на регулярній основі.
Це велике питання, яке, мабуть, заслуговує на велику кількість туди-сюди, але я думаю, що воно може слугувати пробним каменем для багатьох важливих бесід, які повинні мати такі нові розробники, як я. Я просто намагаюся зрозуміти, що я роблю не так, як я можу поліпшитись або як мені, можливо, навіть почати з нуля та спробувати інший підхід.
Ще одне, що мене хвилює у цій моделі, це те, що вона працює, базуючись на нещодавно, а не на релевантності. Якщо хтось може підказати, як це можна покращити, щоб покращити свою актуальність, я був би всім вухом. Я використовую API Directed Edge для генерації рекомендацій, але, схоже, для чогось на зразок стрічки новин рекомендувачі не працюватимуть (оскільки раніше нічого не було вибране!).