Мне нужен совет о 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 все еще кажется настолько эффективным и логичным, поэтому я останусь с ним, пока проект не подгонит соблазн.