Есть вот такая задачка, которую проще описать на конкретных примерах
Пример #1: LiveJournal — Лента постов друзей
Пример #2: Одноклассники — Лента активности друзей
Задача по сути одна и таже: есть что-то (посты, действия) упорядоченное
во времени и принадлежащее пользователю, плюс есть отношение между
пользователями (в случае LiveJournal имеем одностороннее отношение, в
случае Одноклассников — обоюдостороннее).
Собственно надо решить проблему в свете больших нагрузок и
масштабируемости. Я пока вижу два варианта, и оба мне не нравятся.
Естественно, выборка подразумевает загрузку N записей, начиная с I-й
(обыкновенный пейджинг). Также, независимо от реализации, выборки будут
кэшироваться на какое-то допустимое время (в пределах нескольких минут).
1. JOIN между таблицей моих друзей и их артефактов. По реализации вижу
два варианта этого процесса.
1.1. Сканирование таблицы артефактов упорядоченных по убыванию даты и
сравнение их владельцев с выбранным списком друзей. В этом варианте
используется натуральный порядок артефактов (кластерный индекс), никаких
временных таблицы и файловых сортировок. Но — если наши друзья ничего не
писали, то мы таким образом можем вообще прогуляться по всей таблице
артефактов.
1.2. Выборка списка артефактов по каждому другу, и затем слияние этих
списков. Судя по отчетам MySQL в этом будет использоваться временная
таблица с последующим FILESORT. Будет плохо, если артефактов у друзей
очень много. Ограничивать выборку артефактов по времени?
2. Ввести таблицу "лента" (пользователь.ленты — дата.создания.артефакта
— id.артефакта). При создании артефакта пользователем — подгружать
список его друзей и в ленту каждого записывать информацию о только что
созданном артефакте. Выборка для уже другого пользователя в данном
случае вообще идеальна — используется индекс таблицы ленты по связке
(пользователь.ленты — дата.создания.артефакта). Но непонятно что делать
в случае создания отношения между пользователями — добавлять уже
созданные к данному моменту артефакты задним числом? Или просто их
игнорировать?
В общем, мне кажется, что должен существовать "ход конем" которого я не
вижу... или нет?
Posted via RSDN NNTP Server 2.1 beta
mazurkin пишет:
> Собственно надо решить проблему в свете больших нагрузок и
> масштабируемости. Я пока вижу два варианта, и оба мне не нравятся.
В свете больших нагрузок я бы выбрал что-то более близкое к варианту 2, т.к. вариант 1 банально ограничен одной БД, и при шардинге потребует лишнего дублирования информации.
А так — в хранилище #N имеем профиль юзера M, в котором есть такой объект как "лента активности друзей". Событие от друга броадкастится по инстансам его друзей (читателей в случае ЖЖ), включая нашего юзера M, и обрабатывается на его стороне — кладется в ленту. Также никто не мешает вести ленту собственных действий — тогда в случае добавления нашего юзера в друзья или банального сбоя мы на основании этого первоисточника все восстанавливаем.
Posted via RSDN NNTP Server 2.1 beta