Мне нужен совет о NoSQL/MongoDb и структуре данных/моделей

Недавно я изучаю базы данных NoSQL. Мне нужен совет о том, как хранить данные наиболее оптимальным и эффективным способом для данной проблемы. Сейчас я нацелен на MongoDB. Однако это должно быть то же самое с CouchDB.

Скажем, у нас есть эти 3 Модели:

Story:
 id
 title

User:
 id
 name

Vote:
  id
  story_id
  user_id

Я хочу иметь возможность задавать в базе данных следующие вопросы:

  • Кто голосовал за эту историю?
  • Что этот пользователь проголосовал за?

Я делаю простые объединения при работе с реляционной БД. Вопрос в том, как я должен хранить данные для этих объектов, чтобы быть наиболее эффективными.

Например, если я храню объекты Vote в качестве подмножества Stories, то будет легко получить информацию - "За что проголосовал пользователь".

Ответ 1

Я предлагаю хранить голоса в виде списка истории _id для каждого пользователя. Таким образом, вы можете узнать, какие истории проголосовали пользователи, просто просмотрев список. Чтобы получить пользователей, проголосовавших за историю, вы можете сделать что-то вроде:

db.users.find({stories: story_id})

где story_id - _id рассматриваемой истории. Если вы создадите индекс в поле stories, оба этих запроса будут быстрыми.

Ответ 2

  • не беспокойтесь, если ваши запросы эффективны, пока они не начнут действовать.
  • согласно приведенной ниже цитате, вы делаете это неправильно

То, как я занимаюсь ум должен забыть о база данных все вместе. в реляционный мир db, вы всегда должны беспокоиться о нормализации данных и ваша структура таблицы. Отбросьте все это. Просто разместите свою веб-страницу. Положите их все вон. Теперь посмотри на них. Ваш уже 2/3. Если вы забудете что размер базы данных имеет значение и данные не должны дублироваться, 3/4, и вам даже не пришлось напишите любой код! Пусть ваши взгляды диктуют ваши модели. Вам не нужно принимать ваши объекты и сделайте их 2 как в реляционный мир. Вы можете хранить объекты с формой теперь.

how-to-think-in-data-stores-instead-of-databases

Ответ 3

Хорошо, вы предоставили нормализованную модель данных, как и в настройке SQL.

В моем понимании вы не делаете этого в MongoDB. Вы можете хранить ссылки, но не по соображениям производительности в общем случае.

Я не эксперт в области NoSQL никоим образом, но почему бы вам просто не следовать вашим потребностям и не хранить пользователей (ids), которые проголосовали за историю в коллекции историй и истории (ids) пользователь проголосовал за коллекцию пользователей?

Ответ 4

В CouchDB это очень просто. Вызывается один вид:

function(doc) {
 if(doc.type == "vote") {
   emit(doc.story_id, doc.user_id);
 }
}

Другое изображение испускает:

function(doc) {
 if(doc.type == "vote") {
   emit(doc.user_id, doc.story_id);
 }
}

Оба запроса очень быстрые, так как нет соединения. Если вам нужны данные пользователя или данные истории, CouchDB поддерживает выборку нескольких документов. Также довольно быстро и является одним из способов сделать "соединение".

Ответ 5

В последнее время я много изучал MongoDB и CouchDB, но мое понимание ограничено. Тем не менее, когда вы думаете о сохранении голосов внутри документа истории, вам, возможно, придется беспокоиться о том, чтобы поразить ограничение размера документа размером 4 МБ. Даже если вы этого не сделаете, вы можете постоянно увеличивать размер документа, чтобы заставить его перемещаться и, таким образом, замедлять ваши записи (см., Как размеры документов указаны в MongoDB).

Что касается CouchDB, такие вещи довольно просты, изящны и довольно быстны после вычисления индексов представления. Лично, однако, я не решался сделать аналогичный проект в CouchDB из-за контрольных показателей, показывающих его постепенное замедление в значительной степени по мере роста базы данных (и роста индексов). Мне бы хотелось увидеть несколько более свежих тестов, показывающих производительность CouchDB по мере увеличения размера базы данных. Я ХОЧУ попробовать MongoDB или CouchDB, но SQL все еще кажется настолько эффективным и логичным, поэтому я останусь с ним, пока проект не подгонит соблазн.