Схема схемы базы данных 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