Персонализированная логика сходства/непохожести — должна ли она быть перенесена на уровень представления, данных или сервиса?

Хотел узнать, существует ли консенсус относительно того, где должна храниться логика отображения кнопок «нравится/не нравится» — в представлении клиента или в запросе к базе данных. Перенос логики в сам запрос сохраняет его чистоту и согласованность, но потребует персонализации каждого запроса для списка сообщений на домашней странице и запрета кэширования этого запроса.

Установка: база данных MongoDb (или, возможно, neo4j), API-интерфейс node.js и сервер приложений, мобильный клиент iOS и веб-сайт. У большинства постов может быть около дюжины лайков, но у некоторых могут быть сотни лайков. Большинству пользователей понравились 50–300 сообщений, а некоторым пользователям понравились тысячи сообщений.

Мой вариант использования: пользователь просматривает список последних популярных сообщений и видит кнопку «Нравится» или «Не нравится» рядом с каждым сообщением в зависимости от того, понравилось ли ему сообщение.

Решение-

Подход 1: передать в запросе userid в базу данных и вернуть список самых популярных постов со свойством isLiked, вычисляемым в запросе.

Подход 2. Клиентское приложение извлекает и синхронизирует понравившиеся идентификаторы для этого пользователя, а представление определяет, показывать ли кнопку «Нравится» или «Не нравится» для любого заданного списка сообщений. Списки постов могут кэшироваться на сервере или в cdn и не требуют никакой персонализации.

Подход 3? Есть ли более эффективный способ сделать это на остальном уровне службы API?


person MonkeyBonkey    schedule 09.11.2012    source источник


Ответы (1)


Я думаю, вам нужно рассмотреть преимущества и недостатки и посмотреть, какой из них лучше.

MongoDB поддерживает моноатомную команду увеличения базы данных, которая может быть очень эффективной. Вам даже не придется ждать, пока уровень базы данных подтвердит вставку, и просто отобразит увеличение количества лайков.

Если примерно в то же время другой пользователь читает ту же статью, и вы хотите быть на 100% уверены, что он считает правильно, вы, вероятно, не захотите выполнять какое-либо кэширование.

Сказав это, вам, вероятно, не нужно, чтобы это число было просмотрено последовательно через миллисекунду после того, как кто-то «понравился» сообщению. Таким образом, вы можете кэшировать информацию базы данных, включая количество, и обращаться к базе данных каждые x минут.

Обратите внимание, что посты в блоге очень популярны в первые пару дней, а потом уже нет.

Просто из любопытства вы можете найти это интересным: видео системы подсчета видео YouTube, в которой счетчик некоторое время остается на уровне 301 для проверки и по причинам с несколькими центрами обработки данных. http://www.youtube.com/watch?v=oIkhgagvrjI

person Gianfranco P.    schedule 12.11.2012
comment
У меня проблема с персонализированным свойством isLiked, а не с подсчетом как таковым. Увеличение счетчика было простым и эффективным, но бизнес-логика того, как показать, понравился ли этому пользователю этот пост масштабируемым способом, является проблемой. - person MonkeyBonkey; 13.11.2012
comment
Я думаю, вам следует кэшировать это, возможно, в локальном хранилище браузера, так как пользователь, скорее всего, увидит ту же статью на том же устройстве/браузере. Но вам все равно нужно будет запросить базу данных или какой-нибудь кеш среднего уровня, если он попытается прочитать статью с другого устройства или браузера без локального кеша. -- Если вы предпочитаете, чтобы архитектура была простой, вероятно, «масштабирование» с помощью MongoDB увеличит ваши чтения, как только ваше новостное приложение станет популярным. Это делается с помощью сегментирования. - person Gianfranco P.; 14.11.2012
comment
локальное кэширование в подходе 2 может работать, но кажется, что оно станет очень сложным и подвержено ошибкам при синхронизации. Шардинг в этом случае не поможет, так как проблема не в размере базы данных, а в количестве лайков, которые получит каждый пост, и нет смысла шардировать отдельные записи. - person MonkeyBonkey; 15.11.2012
comment
Каждый лайк будет привязан к конкретному пользователю. Это должно быть уникальным и проиндексированным, поэтому думаю, что вы можете работать с коллекцией userlike { userid: Object(<userid>), postid: Object(<postid>) }. А затем создайте уникальный индекс для userid, db.userlike.ensureIndex({userid:1, postid:1}, {unique: 1}). С базами данных NoSQL вам может потребоваться дублирование данных для повышения производительности. - person Gianfranco P.; 15.11.2012