Почему ключевые имена хранятся в документе в MongodDB

Мне интересно эту цитату от Kyle Banker MongoDB In Action:

Важно учитывать длину имен ключей, которые вы выберете, поскольку имена ключей хранятся в самих документах. Это контрастирует с РСУБД, где имена столбцов всегда хранятся отдельно от строк, на которые они ссылаются. Поэтому, когда вы используете BSON, если вы можете жить с dob вместо date_of_birth в качестве имени ключа, вы сохраните 10 байт на документ. Это может показаться не таким уж большим, но, как только у вас будет миллиард таких документов, вы сохранили почти 10 ГБ пространства для хранения, просто используя более короткое имя ключа. Это не означает, что вы должны идти на необоснованные длины, чтобы обеспечить наименьшее количество ключевых имен; быть разумным. Но если вы ожидаете больших объемов данных, экономия на именах клавиш экономит место.

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

Ответы

Ответ 1

То, о чем вы говорите, часто называют "сжатием ключа" *. Существует несколько причин, по которым он не был реализован:

  • Если вы хотите, вы можете сделать это на уровне Application/ORM/ODM довольно легко.
  • Это не обязательно преимущество производительности ** во всех случаях - считайте коллекции с большим количеством имен ключей и/или именами ключей, которые сильно различаются между документами.
  • Это может не обеспечить ощутимую производительность ** на всех, пока у вас не будет миллионов документов.
  • Если сервер делает это, все ключевые имена ключей по-прежнему должны передаваться по сети.
  • Если имена сжатых ключей передаются по сети, то читаемость действительно страдает от использования консоли javascript.
  • Сжатие всего документа JSON может предложить, дает еще лучшее преимущество в производительности.

Как и все функции, есть анализ затрат-выгод для его реализации и (по крайней мере до сих пор) другие функции предложили больше "взрыва для доллара".

Полное сжатие документа [рассматривается] [1] для будущей версии MongoDB. доступно с версии 3.0 (см. ниже)

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

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

Update

MongoDB версии 3.0 и теперь имеют полную возможность сжатия документов с помощью WiredTiger механизма хранения.

Доступны два алгоритма сжатия: snappy и zlib. Цель заключается в том, чтобы стать лучшим выбором для всесторонней работы, а для zlib - лучший выбор для максимальной емкости.

В моем личном (ненаучном, но связанном с коммерческим проектом) эксперименте, мгновенное сжатие (мы не оценили zlib) предложили значительно улучшенную плотность хранения без заметных затрат на чистую производительность. Фактически, в некоторых случаях была немного более высокая производительность, что примерно соответствовало моим предыдущим комментариям/прогнозам.

Ответ 2

Я считаю, что одной из первоначальных причин хранения имен ключей с документами является предоставление более легко масштабируемой без схемы базы данных. Каждый документ является автономным в большей степени, поскольку если вы перемещаете документ на другой сервер (например, через репликацию или очертание), вы можете индексировать содержимое документа без необходимости ссылки на отдельные или централизованные метаданные, такие как сопоставление от имени ключей до более компактных идентификаторов ключей.

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

В зависимости от вашего варианта использования имена ключей могут или не должны потреблять значительную часть пространства относительно сопутствующих данных. Вы всегда можете обойти проблему хранения с помощью реализации приложения /ODM путем сопоставления YourFriendlyKeyNames с более короткими эквивалентами ключей базы данных.

Существует открытая проблема MongoDB Jira, и некоторые дальнейшие обсуждения содержат имена токенов сервера, которые вы можете проголосовать, чтобы помочь определить приоритеты, включая эта функция в будущей версии.

Текущие цели проекта MongoDB включают производительность с динамическими схемами, репликацию и высокую доступность, автоматическое отрисовку и обновление на месте.. с одним потенциальным компромиссом, являющимся дополнительным дисковым использованием.

Ответ 3

Необходимость искать это в базе данных для каждого запроса будет серьезным штрафом.
Большинство драйверов позволяют вам указывать ElementName, поэтому MyLongButReadablePropertyName в вашей модели домена становится mlbrpn в mongodb.

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

db.myCollection.find({"MyLongButReadablePropertyName" : "some value"})

в

db.myCollection.find({"mlbrpn" : "some value"})

Эффективные драйверы, такие как кеш-драйвер С#, отображают это сопоставление, поэтому нет необходимости искать это для каждого запроса.

Возвращаясь к названию вашего вопроса:

Почему ключевые имена хранятся в документе в MongodDB

Это единственный способ поиска документов?
Без сохраненных имен ключей не было ключа для поиска.

Надеюсь, что это поможет