Схема схемы базы данных MongoDB
У меня есть сайт с пользователями 500 тыс. (работает на SQL Server 2008). Теперь я хочу включить потоки активности пользователей и их друзей. После тестирования нескольких вещей на SQL Server становится очевидным, что RDMS не является хорошим выбором для этой функции. он медленный (даже когда я сильно де-нормализовал свои данные). Поэтому, посмотрев на другие решения NoSQL, я понял, что могу использовать MongoDB для этого. Я буду следить за структурой данных на основе activitystrea.ms
json спецификации для потока активности
Поэтому мой вопрос: какой будет лучший дизайн схемы для потока активности в MongoDB (с этим большим количеством пользователей вы можете в значительной степени предсказать, что он будет очень тяжелым для записи, поэтому мой выбор MongoDB - это отличная производительность записи. Я подумал о трех типах структур, скажите, пожалуйста, если это имеет смысл или я должен использовать другие схемы схемы.
1 - Храните все действия со всеми друзьями/последователями в этом шаблоне:
{
_id:'activ123',
actor:{
id:person1
},
verb:'follow',
object:{
objecttype:'person',
id:'person2'
},
updatedon:Date(),
consumers:[
person3, person4, person5, person6, ... so on
]
}
2 - Второй дизайн: Collection name-activity_stream_fanout
{
_id:'activ_fanout_123',
personId:person3,
activities:[
{
_id:'activ123',
actor:{
id:person1
},
verb:'follow',
object:{
objecttype:'person',
id:'person2'
},
updatedon:Date(),
}
],[
//activity feed 2
]
}
3 - Этот подход будет состоять в том, чтобы хранить элементы активности в одной коллекции, а потребители - в другой. В действиях у вас может быть такой документ, как:
{ _id: "123",
actor: { person: "UserABC" },
verb: "follow",
object: { person: "someone_else" },
updatedOn: Date(...)
}
И затем, для последователей, у меня будут следующие документы "уведомлений":
{ activityId: "123", consumer: "someguy", updatedOn: Date(...) }
{ activityId: "123", consumer: "otherguy", updatedOn: Date(...) }
{ activityId: "123", consumer: "thirdguy", updatedOn: Date(...) }
Ваши ответы с благодарностью.
Ответы
Ответ 1
Я бы пошел со следующей структурой:
-
Используйте одну коллекцию для всех действий, которые произошли, Actions
-
Используйте другую коллекцию для тех, кто следует, Subscribers
-
Используйте третью коллекцию, Newsfeed
для определенного фида новостей пользователя, элементы разворачиваются из коллекции Actions
.
Коллекция Newsfeed
будет заполнена рабочим процессом, который асинхронно обрабатывает новый Actions
. Поэтому новостные ленты не будут заполняться в режиме реального времени. Я не согласен с Geert-Jan в том, что в реальном времени важно; Я считаю, что большинство пользователей не заботятся о какой-либо задержке в большинстве (не всех) приложений (для реального времени я бы выбрал совершенно другую архитектуру).
Если у вас очень большое количество consumers
, разветвление может занять некоторое время, правда. С другой стороны, включение потребителей прямо в объект не будет работать с очень большим количеством следящих элементов, и это создаст слишком большие объекты, которые занимают много индексного пространства.
Самое главное, однако, дизайн вентилятора намного более гибкий и позволяет подсчитывать релевантность, фильтровать и т.д. Я недавно написал сообщение в блоге о схема схемы подачи новостей с MongoDB, где я более подробно объясняю эту гибкость.
Говоря об гибкости, я был бы осторожен в этой спецификации activitystrea.ms. Кажется, это имеет смысл как спецификация взаимодействия между различными провайдерами, но я не буду хранить всю эту подробную информацию в своей базе данных, если вы не собираетесь собирать действия из различных приложений.
Ответ 2
Я считаю, что вы должны посмотреть на свои шаблоны доступа: какие запросы вы, вероятно, будете выполнять больше всего на этих данных и т.д.
Для меня прецедентом, который должен быть самым быстрым, является возможность подталкивать определенную деятельность к "стене" (в терминах fb) каждого из "потребителей активности" и делать это сразу же, когда происходит действие.
С этой точки зрения (я не думал об этом много), я бы пошел с 1, так как 2. кажется, что пакетные действия для определенного пользователя перед их обработкой? Таким образом, если не удается "немедленная" необходимость обновления. Более того, я не вижу преимущества 3. более 1 для этого случая использования.
Некоторые улучшения на 1? Спросите себя, действительно ли вам нужна гибкость в определении множества потребителей для каждого вида деятельности. Нужно ли это указывать на этом мелкомасштабном масштабе? вместо этого не хватало бы ссылки на "друзей" "актера"? (Это будет много места в долгосрочной перспективе, так как я вижу, что массив потребителей является основной частью всего сообщения для каждого вида деятельности, когда потребители обычно располагаются в сотнях (?).
на несколько связанную заметку: в зависимости от того, как вы, возможно, захотите реализовать уведомления в реальном времени для этих потоков активности, возможно, стоит посмотреть на Pusher - http://pusher.com/ и аналогичные решения.
HTH