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

MongoDB и составные первичные ключи

Я пытаюсь определить лучший способ работы с составным первичным ключом в mongo db. Основной ключ для взаимодействия с данными в этой системе состоит из 2 uuids. Сочетание uuids гарантировано будет уникальным, но ни одна из отдельных uuids не будет.

Я вижу пару способов управления этим:

  • Используйте объект для первичного ключа, который состоит из двух значений (как предлагается здесь)

  • Использовать стандартный автогенерированный идентификатор объекта mongo в качестве первичного ключа, сохранить мой ключ в двух отдельных полях, а затем создать составной индекс для этих двух полей

  • Сделать первичный ключ хешем из 2 uuids

  • Некоторое другое удивительное решение, о котором я в настоящее время не знаю

Каковы последствия этих подходов к производительности?

Для варианта 1 я беспокоюсь о том, что производительность вставки зависит от наличия последовательных ключей. Я знаю, что это может убить традиционные системы РСУБД, и я видел признаки того, что это может быть верно и в MongoDB.

Для варианта 2 кажется странным иметь первичный ключ, который никогда не будет использоваться системой. Кроме того, похоже, что производительность запросов может быть не такой хорошей, как в варианте 1. В традиционной RDBMS кластерный индекс дает лучшие результаты запроса. Насколько это уместно в MongoDB?

Для параметра 3 это создало бы одно поле id, но при вставке оно не будет последовательным. Существуют ли другие плюсы и минусы этого подхода?

Для варианта 4, ну... что такое вариант 4?

Кроме того, есть некоторое обсуждение возможности использования CouchDB вместо MongoDB в какой-то момент в будущем. Использует ли CouchDB другое решение?

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: некоторый фон об этой проблеме можно найти здесь

4b9b3361

Ответ 1

Вы должны пойти с опцией 1.

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

Для варианта 1 я беспокоюсь о том, что производительность вставки не последовательные ключи. Я знаю, что это может убить традиционные системы РСУБД и я видел признаки того, что это может быть верно и в MongoDB.

Ваши другие варианты не избегают этой проблемы, они просто переносят ее из индекса _id на вторичный уникальный индекс, но теперь у вас есть два индекса, один раз правильно сбалансированный, а другой - произвольный.

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

Как выработка того, почему вы должны быть уверены, что вы всегда заказываете два значения UUID одинаково, при сравнении поддокументов { a:1, b:2 } не равно { b:2, a:1 } - у вас может быть коллекция, в которой два документа имели эти значения для _Я бы. Поэтому, если вы сначала сохраняете _id с полем, тогда вы всегда должны сохранять этот порядок во всех ваших документах и ​​запросах.

Другая осторожность заключается в том, что индекс для _id:1 будет полезен для запроса:

db.collection.find({_id:{a:1,b:2}}) 

но он не будет использоваться для запроса

db.collection.find({"_id.a":1, "_id.b":2})

Ответ 2

У меня есть вариант 4 для вас:

Используйте автоматическое поле _id и добавьте 2 одиночных индекса поля для обоих uuid вместо одного составного индекса.

  • Индекс _id будет последовательным (хотя это менее важно в MongoDB), легко масштабируется, и вы можете позволить MongoDB управлять им.
  • 2 индекса uuid позволяют вам делать любой запрос, который вам нужен (с первым, со вторым или с обоими в любом порядке), и они занимают меньше места, чем один составной индекс.
  • Если вы используете оба индекса (и другие), в том же запросе MongoDB будет пересечь их (новый в v2. 6), как если бы вы использовали составной индекс.

Ответ 3

Я бы пошел с вариантом 2. Вы все равно можете сделать индекс, который обрабатывает как поля UUID, так и производительность должна быть такой же, как составной первичный ключ, за исключением того, что с ним будет намного легче работать.

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

Ответ 4

Я бы выбрал вариант 2, и есть почему

  • Наличие двух отдельных полей вместо одного, объединенного из обоих uuids, как предложено в 1-м, предоставит вам гибкость для создания других комбинаций индексов для поддержки будущих запросов запросов или, если окажется, что мощность одного ключа выше затем другой.
  • наличие не последовательных ключей может помочь вам избежать горячих точек при вставке в оштукатуренную среду, поэтому ее не такой уж плохой вариант. По моему мнению, Sharding - наилучший способ масштабирования вложений и обновлений в коллекциях, поскольку блокировка записи находится на уровне базы данных (до версии 2.6) или уровне сбора (версия 2.6).