Логика базы данных агрегатора каналов для многопользовательского взаимодействия - PullRequest
2 голосов
/ 23 декабря 2011

Я создаю агрегатор каналов (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 ]

2 голосов
/ 28 декабря 2011

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

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

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

0 голосов
/ 23 декабря 2011

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

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

...