Логика базы данных агрегатора каналов для многопользовательского взаимодействия

Я создаю агрегатор каналов (RSS, Twitter, другие службы и т. Д.) С помощью LAMP. Он очень похож на Google Reader в том, что люди могут добавлять столько каналов, сколько они хотят, а затем смогут читать свои каналы, сортировать их, просматривать отдельные каналы или группы каналов одновременно.

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

На этот раз, однако, я создаю сервис, на который люди могут подписаться, поэтому у меня будут потенциально (в идеале) тысячи пользователей и десятки тысяч каналов, и, в свою очередь, миллионы элементов каналов.

Мой подход к схеме базы данных (упрощенно) заключается в следующем:

users (id, name, ...)
feeds (id, name, url, ...)
feed_items (id, title, timestamp, feed_id, ... )
user_feeds (id, user_id, feed_id, ...)

Однако, поскольку пользователь может подписаться на 100 каналов, я пытаюсь спланировать лучший и наиболее оптимизированный способ запроса базы данных для feed_items каналов, на которые он подписан (или подмножеств).

2 ответа

Решение

Я думаю, что вы на правильном пути. Я делал это раньше (пару раз), и важно выяснить, какая таблица должна содержать какую информацию. Например, в моей таблице USERS я храню кеш-копию списка подписок пользователя (или OPML). Если вы хотите, чтобы пользователи могли отслеживать состояние чтения / непрочитания каждой статьи, возможно, вы захотите сохранить эти метаданные в отдельной таблице. И наоборот, я вижу, что вы создали реляционную таблицу только для пользовательских<->отношений с фидами. Это позволяет хранить только одну копию каждого канала в таблице FEED, но компромисс в сложности запросов (и производительности) может не стоить этого. Подумайте, какие запросы вы ожидаете выполнить.

Например, главная "домашняя страница" моих пользователей - это список "папок" (т. Е. Ярлыков Google Reader), в которые разделены фиды, причем каждая папка помечена количеством непрочитанных статей в этой папке (не считая дублирующихся статей)., Даже при хороших показателях это медленный запрос (и медленный), использующий реляционный подход. Но если вы денормализуете его (т. Е. Таблица FEEDS может содержать несколько копий каждого канала, а схема включает в себя user_id (и, в моем случае, имя папки)), таблица будет больше, но этот запрос будет простым и мгновенным.

Кроме того, в своей таблице POSTS (или FEED_ITEMS - как угодно) я сохранил оригинальное описание / содержание статьи: закодировано в столбце DESCRIPTION_ORIGINAL, а затем поместил "чистую" версию в столбце DESCRIPTION. Чистая версия очищена с помощью HTML, удалена реклама, устранены известные проблемы с кодировкой и т. Д.

Кэширование здесь невероятно полезно. Вы можете, когда пользователь редактирует свои каналы, выполнить запрос канала и сохранить результаты в memcache.

Тогда вы можете просто сделать WHERE (feed_items.feed_id IN ( ... ))Хотя я рекомендую вам также кешировать результаты этих запросов.

Другие вопросы по тегам