#mongodb #mongodb-indexes
#mongodb #mongodb-индексы
Вопрос:
Поскольку ObjectId хранится в 12 байтах и даже не подходит для ключа сегмента, я спрашиваю себя, не лучше ли вместо этого использовать совершенно случайный int64 (8 байт) для _id ?
моя идея, создать полностью случайный int64, посмотреть, не присутствует ли он уже в коллекции (в основном это не так, псевдослучайный генератор работает хорошо), если нет, то создайте документ с этим _id . итак, у нас есть _id, который использует только 8 байт и хорошо работает для ключа сегмента
что вы об этом думаете?
Комментарии:
1. На мой взгляд, это дизайнерское решение, и я не уверен, почему вы выбрали ObjectId для разделения. Концепция сегментирования заключается в распределении нагрузки. Так что подумайте, на какое поле имело бы смысл распределить нагрузку в вашем проекте.
Ответ №1:
Я бы настоятельно рекомендовал вам никогда не использовать случайно сгенерированное число в качестве уникального идентификатора. Во-первых, вам всегда придется проверять его существование при вставке новой записи, потому что вы никогда не сможете по-настоящему создать уникальное случайное число. Другая довольно очевидная причина заключается в том, что int64 имеет ограничение.
Используйте ObjectId для вашего _id, это то, для чего он предназначен, или, если у вас есть очень веская причина не делать этого, используйте GUIDS
Смотрите здесь:
Комментарии:
1. но ObjectId нельзя использовать как shardkey, так что это означает, что мне нужно будет иметь другой индекс в памяти (возможно, хэш ObjectId)
2. Вы помечаете другое поле случайно сгенерированным номером и используете его в качестве своего ключа сегмента, если действительно хотите, или включаете нечисловые символы и разрабатываете более уникальный способ генерации уникальных ключей. Сегментный ключ не обязательно должен состоять из одного поля, вы могли бы использовать составной сегментный ключ. Я бы не стал использовать случайное число для вашего _id. Я обновил свой ответ, включив ссылку для вас на ключи сегментов
3. @loki Его можно использовать как ключ сегмента, только он очень плохой.
4. @pieperu ObjectId по умолчанию используется для _id , но чего-либо уникального вполне достаточно и сильно зависит от варианта использования. В некоторых случаях даже проверяются адреса электронной почты. Ключи сегментов, однако, не обязательно должны быть уникальными. Совсем наоборот. Возьмем, к примеру, экономические регионы (EMEA, APAC, NCSA). Если вы хотите, чтобы ваши сегменты были близки к вашим клиентам, вполне может быть, что эти три значения станут отличным ключом сегментов.
5. Я согласен, моя точка зрения заключается в том, что случайное число не уникально, и чтобы сделать это так, потребуются некоторые усилия для проверки того, что случайное число уже не является существующим _id . Как я уже говорил выше, случайная буквенно-цифровая строка лучше, чем случайное число, если она должна быть уникальной. Да, я также согласен с тем, что ключ сегмента не обязательно должен быть уникальным, совсем наоборот. Следовательно, почему я поделился этой ссылкой в своем ответе
Ответ №2:
Отличное решение — взять ObjectId() и переместить первые 4 байта в конец ObjectId. Этот новый ObjectId абсолютно уникален, и его можно использовать как ключ сегмента, потому что он НЕ имеет линейно возрастающего типа.
Комментарии:
1. Что является своего рода накладными расходами.
_id
Полем может быть что угодно , так зачем возиться с этим. UUID был бы таким же хорошим.2. но uuid занимает 16 байт? это не имеет значения?