Производительность MongoDB: архитектура новостной ленты, подписчики, комментарии - PullRequest
1 голос
/ 28 января 2012

Я использую MongoDB + PHP для "фейсбукистской" ленты новостей с различными видами каналов (пост, фото, опрос и т. Д.) И с комментариями.

Каждый канал принадлежит какому-то "каналу" - в настоящее время этоможет быть пользователь или группа (в будущем может быть больше контейнеров).

Любой пользователь может подписаться на любой канал или отказаться от него.

Теперь давайте скажем, что есть тонны каналов и тонны каналов.Какова наилучшая структура для каналов / каналов / комментариев?

Я думаю о двух подходах:

1) Сбор каналов со списком подписчиков в каждом канале:

feeds: 
[
   {date_added: ..., 
    last_update: ..., 
    title: ...,
    text: ...,
    channel: ..., 
    channel_subscribers: [...],
    comments_subscribers: [...],
    comments: [...] 

   },
   {...},
   {...},
   {...}
]

Если я хочу получать последние новости:

db.feeds.find({date_added: "this week", channel_subscribers: "my_login"});

Если я хочу получать новости с новыми комментариями:

db.feeds.find({last_update: "this week", comments_subscribers: "my_login"});

Плюсы:

  • Простые и быстрые показания?

Минусы:

  • Когда я хочу подписаться / отписатьсядля / из канала мне нужно запустить через все каналы и нажать / вытащить мое имя из списка channel_subscribeers;это может быть медленным, если у меня есть тонны каналов

2) Отдельная коллекция "каналов": То же самое, но сохранить список подписчиков в коллекции каналов:

channels: 
[
  {channel_id:..., last_update: ..., subscribers: [...]},
  {channel_id:..., last_update: ..., subscribers: [...]}
]

Сначала я должен запросить последние обновленные каналы:

subscribes = db.channels.find({last_update: "today", subscribers: "my_login"})

Теперь найдите мои каналы:

db.feeds.find({channel: {$in: subscribes}], date_added: "today"})

Плюсы:

  • Простая, быстрая и более безопасная подписка / отмена подписки;

Минусы:

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

3) Сохранять пользователей в коллекции пользователей (таким образом, у каждого пользователя есть массивего собственные подписки)

users:
[
  {_id: ..., login: ..., email: ..., subscribes: [...]}
]

Минусы: - в этом случае у нас будет еще больший массив для вставки внутрь $ in, чем в предыдущем (# 2) подходе.

4) Ваши предложения?

1 Ответ

1 голос
/ 30 января 2012

ОК, я отвечу сам.Я попытался сделать тест на моем ноутбуке Windows 7 32 бит / 2 ГБ оперативной памяти.Я создал коллекцию «фидов» и заполнил ее 500 фидами:

feeds:
[
 {_id: ..., subscribers: [...]},
 {_id: ..., subscribers: [...]},
]

Каждый массив «подписчиков» содержит список из 2000 коротких случайных названий строк.

Сначала я должен упомянуть, чторазмер моей БД увеличился с 60 МБ до 1,5 ГБ.

Затем, когда я запустил команду оболочки db.feeds.ensureIndex({subscribers: 1}), она зависла на ~ 3 минуты и затем остановилась с ошибкой: "can't map file memory - mongo requires 64 bit build for larger datasets".

определенно не очень хорошая идея создавать такие большие многопользовательские поля внутри документов Монго.

...