MongoDB и составные первичные ключи
Я пытаюсь определить лучший способ справиться с составным первичным ключом в Mongo db. Основной ключ для взаимодействия с данными в этой системе состоит из 2 UUID. Сочетание uuids гарантированно будет уникальным, но ни один из отдельных uuids не является.
Я вижу несколько способов управления этим:
использовать объект для первичного ключа, который состоит из 2 значений (как предложил здесь)
используйте стандартный автоматически сгенерированный идентификатор объекта mongo в качестве первичного ключа, сохраните мой ключ в двух отдельных полях, а затем создайте составной индекс на этих двух полях
сделайте первичный ключ хэшем из 2 UUID
какое-то другое удивительное решение, о котором я в настоящее время не знаю
каковы последствия этих подходов для производительности?
для Вариант 1, я беспокоюсь о производительности вставки из-за наличия не последовательных ключей. Я знаю, что это может убить традиционные системы РСУБД, и я видел признаки того, что это может быть верно и в MongoDB.
для варианта 2 кажется немного странным иметь первичный ключ, который никогда не будет использоваться системой. Кроме того, кажется, что производительность запросов может быть не такой хорошей, как в варианте 1. В традиционной СУБД кластеризованный индекс дает лучшие результаты запроса. Насколько это актуально в В MongoDB?
для варианта 3 это создаст одно поле id, но опять же оно не будет последовательным при вставке. Есть ли другие плюсы/минусы этого подхода?
для варианта 4, хорошо... какой вариант 4?
кроме того, есть некоторое обсуждение возможности использования CouchDB вместо MongoDB в какой-то момент в будущем. Будет ли использование CouchDB предлагать другое решение?
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: некоторые предпосылки о проблеме могут быть найдено здесь
4 ответов
вы должны пойти с вариантом 1.
основная причина в том, что вы говорите, что беспокоитесь о производительности - использование индекса _id, который всегда есть и уже уникален, позволит вам сэкономить на поддержании второго уникального индекса.
для варианта 1 я беспокоюсь о производительности вставки, чтобы иметь не последовательные ключи. Я знаю, что это может убить традиционные системы РСУБД и я видел признаки того, что это может быть правдой в MongoDB как что ж.
ваши другие параметры не избегают этой проблемы, они просто переносят ее из индекса _id во вторичный уникальный индекс - но теперь у вас есть два индекса, как только это правильно сбалансировано, а другой-случайный доступ.
существует только одна причина для вопроса Вариант 1, и это если вы планируете получить доступ к документам только одним или только другим значением UUID. Пока вы всегда предоставляете оба значения и (эта часть очень важна) вы всегда заказываете их одинаково во всех ваших запросах, тогда индекс _id будет эффективно служить своему полному назначению.
в качестве уточнения, почему вы должны убедиться, что вы всегда заказываете два значения UUID одинаково, при сравнении поддокументов { a:1, b:2 }
не равно { b:2, a:1 }
- у вас может быть коллекция, в которой два документа имели эти значения для _id. Поэтому, если вы сначала храните _id с полем a, вы всегда должны сохранять этот порядок во всех своих документах и запросах.
в другое предостережение-это индекс на _id:1
будет использоваться для запроса:
db.collection.find({_id:{a:1,b:2}})
но это не можно использовать для запроса
db.collection.find({"_id.a":1, "_id.b":2})
у меня есть вариант 4 для вас:
использовать автоматическую _id
field и добавьте 2 одиночных индекса поля для обоих uuid вместо одного составного индекса.
- на
_id
индекс будет последовательным (хотя это менее важно вMongoDB
), легко сегментируемые, и вы можете позволитьMongoDB
управлять ею. - индексы 2 uuid позволяют вам сделать любой запрос, который вам нужен (с первым, со вторым или с обоими в любом порядке), и они занимают меньше космоса чем 1 составной индекс.
- если вы используете оба индекса (и другие) в одном запросе
MongoDB
будет пересечение их (новое в v2.6) как если бы вы использовали составной индекс.
Я ЗА 2 вариант и вот почему
- наличие двух отдельных полей вместо одного, объединенного с обоими UUID, как предложено в 1st, оставит вам возможность создавать другие комбинации индексов для поддержки будущих запросов запросов или, если окажется, что мощность одного ключа выше, чем другой.
- имеющие номера последовательных ключей может помочь вам избежать горячих точек при вставке в сегментированной среде, поэтому его не такая уж и плохая выбор. Sharding-лучший способ, на мой взгляд, масштабировать вставки и обновления в коллекциях, поскольку блокировка записи находится на уровне базы данных (до 2.6) или на уровне коллекции (версия 2.6)
Я бы пошел с вариантом 2. Вы все равно можете сделать индекс, который обрабатывает оба поля UUID, и производительность должна быть такой же, как составной первичный ключ, за исключением того, что с ним будет намного проще работать.
кроме того, по моему опыту, я никогда не жалел, что дал что-то уникальное удостоверение личности, даже если это не было строго необходимо. Возможно, это непопулярное мнение.