Подтвердить что ты не робот

Моделирование отношений в MongoDB

Будучи одним из самых популярных решений NoSQL, MongoDB имеет большинство преимуществ этого подхода. Но одна проблема, с которой я все еще сталкиваюсь, заключается в том, как отражать отношения объектов в хранилище данных NoSQL, в частности - MongoDB.

Например, рассмотрим простую модель данных: пользователь, сообщение и комментарий. Мне ясно, что комментарии не имеют ценности сами по себе и, таким образом, становятся встроенными объектами для сообщений. Но когда дело доходит до пользователей - это становится сложно, потому что Пользователь сам по себе является сущностью, а не связью с Post. Теперь, если мне нужно будет отображать сообщения с полными именами пользователей и ссылками на профили на веб-странице, мне нужно будет иметь список сообщений и информации об авторах сообщений (по крайней мере, имя и идентификатор).

Я вижу здесь 2 возможных решения:

  • Де-нормализовать данные таким образом, чтобы каждая запись в записи содержала его идентификатор автора и полное имя (и любые другие атрибуты пользователя, которые могут потребоваться при публикации сообщений). Таким образом, я бы запросил данные очень просто, но когда пользователь обновляет свой профиль, мне нужно будет обновить все сообщения пользователя. Но тогда мне также нужно хранить атрибуты пользователя в объектах комментариев, что означает, что обновление профиля пользователя по существу требует, чтобы я обновил все сообщения, у которых есть хотя бы один комментарий пользователя, если я не хочу хранить комментарии в отдельных коллекциях.
  • Сохранять только идентификатор пользователя в почтовом объекте и запускать 2 запроса: один для получения списка сообщений, а другой - для получения списка пользователей, где идентификатор пользователя находится в списке авторов сообщений. Это требует 2 запросов и дополнительной обработки в моем коде приложения для сопоставления пользователей с сообщениями.

Я уверен, что я не первый, кто столкнулся с этой проблемой, но, к сожалению, до сих пор я не нашел лучших практик в этой теме. Мнения?

4b9b3361

Ответ 1

Оба являются допустимыми решениями, преимущество решения 1 заключается в том, что вы можете показать страницу, подобную этой, с извлечением только одного документа из db. Пользователи не обновляют свой профиль очень часто, и вы можете обновлять все сообщения и встроенные комментарии async после изменения профиля пользователя. Вы можете индексировать сообщения и встроенные комментарии в userid, чтобы обновление было быстрым. Обновление в mongodb очень быстро, потому что mongodb выполняет обновление на месте, и вы не можете откатить или зафиксировать, поэтому mongodb не должен регистрировать изменения.

Однако пользователи на таких сайтах, как stackoverflow, также имеют репутацию, и эта репутация меняется намного больше, чем их профиль.

Решение 2 требует получения большего количества документов на страницу, однако вы можете использовать оператор $in со списком userid (userid post + userid комментариев), поэтому вам нужно только два "selects statements".

Ответ 2

Я столкнулся с подобной проблемой, и именно так я ее решил:

(Когда я решил эту проблему, моя мотивация вождения состояла в том, чтобы избежать объединения)

используйте 2 отдельных коллекции: один для ПОЛЬЗОВАТЕЛЕЙ и один для POSTS. Храните объект пользователя вместе с сообщением в коллекциях сообщений. Не обновляйте коллекцию сообщений при изменении пользовательского объекта. поддержка пользовательской информации - сборник USERS. Уверены, что данные в конце будут содержать устаревшую информацию о пользователе, но как часто пользователь меняет свой профиль.

Если вам нужно показать абсолютную последнюю информацию о пользователе вместе с каждым сообщением, затем получить информацию о пользователе из кеша.

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