Использование UUID вместо ObjectID в MongoDB

Мы переносим базу данных из MySQL в MongoDB по соображениям производительности и рассмотрим, что использовать для идентификаторов документов MongoDB. Мы обсуждаем использование ObjectID, которое является дефолтом MongoDB, или вместо этого используем UUID (это то, что мы использовали до сих пор в MySQL). До сих пор аргументы, которые мы должны поддерживать для любого из этих параметров, следующие:

ObjectIds: ObjectID - это дефолт MongoDB, и я предполагаю (хотя я не уверен), что это по какой-то причине, а это означает, что я ожидаю, что MongoDB сможет обрабатывать их более эффективно, чем UUID, или есть еще одна причина для их предпочтения. Я также нашел qaru.site/info/263074/..., в котором упоминается, что использование ObjectID повышает эффективность индексирования, было бы неплохо, однако, иметь некоторые показатели того, насколько это "более эффективно".

UUID, Наш основной аргумент в пользу использования UUID (и это довольно важный) заключается в том, что они поддерживаются, так или иначе, практически любой базой данных. Это означает, что если какой-то путь вниз мы решаем переключиться с MongoDB на что-то другое по любой причине, и у нас уже есть API, который извлекает документы из БД на основе их идентификаторов, для клиентов этого API ничего не меняется, поскольку идентификаторы могут продолжать быть точно таким же. Если бы мы использовали ObjectIDs, я не совсем уверен, как мы будем переносить их в другую базу данных.

Есть ли у кого-нибудь представление о том, может ли один из этих вариантов лучше других и почему? Вы когда-нибудь использовали UUID в MongoDB вместо ObjectID, и если да, то в чем были преимущества/проблемы, с которыми вы столкнулись?

Ответы

Ответ 1

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

Объектные идентификаторы предоставляются как разумное решение по умолчанию для безопасного времени, генерирующего собственный уникальный ключ (и препятствовать начинающим пользователям пытаться скопировать SQL AUTO INCREMENT, что является плохой идеей в распределенной базе данных).

Не используя ObjectID, вы также пропустите еще одну удобную функцию: ObjectID также включает в себя временную метку unix, когда она была сгенерирована, и многие драйверы предоставляют funtion для ее извлечения и преобразования в дату. Иногда это может сделать отдельное поле create-date избыточным.

Но если вас не беспокоит, вы можете использовать свои UUID как _id.

Ответ 2

Рассмотрим количество данных, которое вы будете хранить в каждом случае.

A MongoDB ObjectID имеет размер 12 байт, упакован для хранения, а его части организованы для производительности (например, timestamp is сохраненный первым, что является логическим критерием упорядочения).

И наоборот, стандартный UUID равен 36 байтам, содержит тире и обычно хранится в виде строки. Кроме того, даже если вы удаляете нечисловые символы и намереваетесь хранить их численно, вы все равно должны довольствоваться своей "индексной" частью (частью UUID v1, основанной на отметке времени), находится в середине UUID, хорошо подходите к сортировке. Есть исследования, которые позволяют использовать исполняемое хранилище UUID, и я даже написал Node.js library, чтобы помочь в ее управлении.

Если вы намерены использовать UUID, подумайте о его реорганизации для оптимальной индексации и сортировки; иначе вы, вероятно, попадете в стену производительности.

Ответ 3

Я нашел эти Benchmarks когда-то, когда у меня был тот же вопрос. Они в основном показывают, что использование Guid вместо ObjectId приводит к снижению производительности индекса.

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