2012-06-18 1 views
6

Я прочитал в описании д.б.н. на основе документа можно, например, встроить все комментарии под постом в том же документе, должность, если вы решили так:В MongoDB практично хранить все комментарии к сообщению в одном документе?

{ 
    _id = sdfdsfdfdsf, 
    title = "post title" 
    body = "post body" 
    comments = [ 
     "comment 1 ......................................... end of comment" 
      . 
      . 
      n 
    ] 
} 

Я, имеющий подобную ситуацию, когда каждый комментарий может быть размером до 8 КБ, и на одну должность может быть до 30 человек.

Несмотря на то, что удобно вставлять комментарии в тот же документ, мне интересно, влияют ли большие документы на производительность, особенно когда сервер MongoDb и HTTP-сервер работают на отдельных компьютерах и должны обмениваться данными по локальной сети?

ответ

0

Короткий ответ: Да и нет.

Предположим, вы пишете блог на основе mongoDB. Вы бы вставляли свои комментарии в свой пост.

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

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

Почему: отправка больших документов через вашу сеть требует времени. И я думаю, бывают ситуации, когда вам не нужен каждый отдельный документ.

TL; 44: Оба варианта работают. Я рекомендую хранить ваши комментарии в отдельной таблице.

+0

Рад, что кто-то поднял проблему с пропускной способностью. Это проблема реального мира, которая часто игнорируется людьми, разрабатывающими решения для такого рода проблем;). Единственное исключение - если вам всегда нужно получать все комментарии для каждого сообщения в блоге, которое вы извлекаете из системы. –

1

Если вы всегда получаете сообщение со всеми его комментариями, почему бы и нет?

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

3

Это очень зависит от операций, которые вы хотите разрешить, но отдельная коллекция обычно лучше.

Например, если вы хотите разрешить пользователям редактировать или удалять комментарии, очень хорошая идея хранить комментарии в отдельной коллекции, так как эти операции трудно или невозможно выразить только с помощью модификаторов атома и указать состояние управление становится болезненным. Документация also covers this.

Ключевой вопрос с комментариями вложения заключается в том, что у вас будут разные авторы. Как правило, сообщение в блоге может быть изменено только авторами блога. Со встроенными комментариями читатель также, таким образом, получает доступ на запись к объекту.

код, как это будет опасно:

post = db.findArticle({ "_id" : 2332 }); 
post.Text = "foo"; 
// in this moment, someone does a $push on the article's comments 
db.update(post); 
// now, we've deleted that comment 
+0

+1 для отдельной коллекции. Общий ответ на этот вопрос заключается в том, чтобы хранить комментарии в одной коллекции, причем большинство людей ссылаются на размер «Войны и мира» в отношении количества контента, который вы можете легко сохранить. См. Группу пользователей MongoDB для многих обсуждений по этому вопросу: https://groups.google.com/forum/?fromgroups#!searchin/mongodb-user/separate$20document$20for$20my$20blog$20comments. BTW, ограничение текущего размера документа - 16 МБ. –

+1

Да, предел в 16 МБ довольно теоретический. Если у вас действительно много комментариев, вам нужна полномасштабная система комментариев или форум - никто не сможет найти свой путь через 13 000 комментариев. Но дизайн схемы имеет последствия для структуры кода, и люди склонны пренебрегать этим. – mnemosyn

+0

Да, согласился ..... –

2

Из соображений производительности это лучше избегать документов, которые могут расти в размерах с течением времени:

Заполнение факторы:

«Когда вы обновляете документ в MongoDB, обновление происходит на месте, если документ не увеличился.Если бы размер документа увеличивался, то , однако, его, возможно, придется переместить на диск, чтобы найти новый диск с достаточным смежным пространством, чтобы он соответствовал новому более крупному документу. Это может привести к проблемам для выполнения записи, если коллекция имеет много индексов, поскольку движение потребует обновления всех индексов для документа.»

http://www.mongodb.org/display/DOCS/Padding+Factor

5

Проводка этот ответ после того, как некоторые другие так Я повторяю некоторые из упомянутых вещей. Пожалуйста, примите первый подходящий ответ, а не этот.

Это говорит о том, что нужно учитывать несколько вопросов. Рассмотрим эти три вопроса:

  1. Всегда ли вы запрашиваете все комментарии при каждом запросе сообщения?
  2. Вы хотите запросить непосредственно комментарии (например, запросить комментарии для конкретного пользователя)?
  3. Будет ли ваша система иметь относительно низкое использование?

Если на все вопросы можно ответить да, вы можете встроить массив комментариев. Во всех других сценариях вам, вероятно, понадобится отдельная коллекция для хранения ваших комментариев.

Прежде всего, вы можете обновлять и удалять комментарии атомарно безопасным способом (см. Обновления с помощью позиционных операторов), но есть некоторые вещи, которые вы не можете сделать, такие как вставки на основе индексов.

Основная проблема использования встроенных массивов для любой крупной коллекции - проблема с обновлением. MongoDB резервирует определенное количество дополнений (см. db.col.stats().paddingFactor) на один документ, чтобы позволить ему расти по мере необходимости. Если у вас закончится это дополнение (и это часто будет в вашем случае), ему придется перемещать этот постоянно растущий документ на диске. Это делает обновления на порядок медленнее и, следовательно, является серьезной проблемой для серверов с высокой пропускной способностью. Связанная, но немного менее важная проблема - это пропускная способность. Если у вас нет другого выбора, кроме как запросить весь пост со всеми его комментариями, даже если вы показываете только первые 10, вы потратите немало трафика, что может быть проблемой для облачных сред (вы можете использовать $ чтобы избежать некоторых из них).

Если вы хотите идти встроенные вот ваши основные опс:

Добавить комментарий:

db.posts.update({_id:[POST ID]}, {$push:{comments:{commentId:"remon-923982", author:"Remon", text:"Hi!"}}}) 

Обновить комментарий:

db.posts.update({_id:[POST ID], 'comments.commentId':"remon-923982"}, {$set:{'comments.$.text':"Hello!"}}) 

Удалить комментарий

db.posts.update({_id:[POST ID], 'comments.commentId':"remon-923982"}, {$pull:{comments:{commentId:"remon-923982"}}}) 

Все это я thods являются безопасными параллелизма, потому что критерии обновления являются частью блокировки записи (процесса).

При всем том, что вы, вероятно, хотите получить специальную коллекцию для своих комментариев, но это происходит со вторым выбором. Вы можете хранить каждый комментарий в выделенном документе или использовать комментарии кодов, скажем, 20-30 комментариев каждый (подробно описано здесь http://www.10gen.com/presentations/mongosf2011/schemascale). У этого есть преимущества и недостатки, поэтому вам решать, какой подход лучше всего подходит для того, что вы хотите сделать.Я бы пошел за ведрами, если ваши комментарии за сообщение могут превышать пару сотен из-за производительности o (N) метода курсора sk (N), который вам понадобится для подкачки. Во всех остальных случаях просто переходите с комментариями к документообороту. Это наиболее гибко с запросом на комментарии для других случаев использования.

Смежные вопросы