Когда вы действительно вынуждены использовать UUID как часть дизайна?

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

Может ли кто-нибудь привести пример, когда у вас нет выбора, кроме как использовать UUID? Из всех видов использования, которые я видел, я вижу альтернативный дизайн без UUID. Конечно, дизайн может быть немного сложнее, но по крайней мере он не имеет ненулевой вероятности сбоя.

UUID пахнет глобальными переменными. Существует много способов сделать глобальные переменные для более простого дизайна, но его ленивый дизайн.

Ответ 1

Я написал генератор/парсер UUID для Ruby, поэтому считаю себя достаточно информированным по этому вопросу. Существуют четыре основные версии UUID:

Версии 4 UUID - это всего лишь 16 байт случайности, выведенных из криптографически безопасного генератора случайных чисел, с некоторым бит-сплетением для идентификации версии и варианта UUID. Они крайне маловероятны, чтобы столкнуться, но это может произойти, если используется PRNG или если вам просто действительно действительно, действительно, действительно, действительно, действительно не повезло.

Версии 5 и Версии 3 UUID используют SHA1 и MD5-хэш-функции соответственно, чтобы объединить пространство имен с частью уже уникальных данных для генерации UUID. Это, например, позволит вам создать UUID из URL-адреса. Столкновения здесь возможны только в том случае, если основная хэш-функция также имеет столкновение.

Версии 1 UUID являются наиболее распространенными. Они используют MAC-адрес сетевой карты (который не поддельный, должен быть уникальным), плюс отметка времени, а также обычное разбиение бит для генерации UUID. В случае машины, у которой нет MAC-адреса, генерируются 6 байтов node с криптографически защищенным генератором случайных чисел. Если два UUID генерируются в последовательности достаточно быстро, чтобы временная метка соответствовала предыдущему UUID, метка времени увеличивается на 1. Коллизии не должны возникать, если не происходит одно из следующих событий: MAC-адрес подменяется; Одна машина, работающая с двумя различными программами UUID, создает UUID в тот же самый момент; Две машины без сетевой карты или без доступа пользователя к MAC-адресу получают одну и ту же случайную последовательность node и генерируют UUID в тот же самый момент; У нас заканчиваются байты, чтобы представить временную метку и вернуться назад к нулю.

Реально, ни одно из этих событий не происходит случайно в одном пространстве ID приложения. Если вы не принимаете идентификаторы, скажем, в масштабе всей сети, или с ненадежной средой, где вредоносные люди могут сделать что-то плохое в случае столкновения с идентификатором, это просто не то, о чем вам следует беспокоиться. Крайне важно понять, что если вы, похоже, будете генерировать ту же самую версию 4 UUID, как и я, в большинстве случаев это не имеет значения. Я создал идентификатор в совершенно другом ID-пространстве от вашего. Мое приложение никогда не узнает о столкновении, поэтому столкновение не имеет значения. Честно говоря, в одном пространстве приложения без злобных актеров исчезновение всей жизни на Земле произойдет задолго до того, как вы столкнетесь, даже на UUID версии 4, даже если вы генерируете довольно много UUID в секунду.

Кроме того, 2 ^ 64 * 16 - 256 экзабайт. Как и в случае, вам нужно будет хранить 256 идентификаторов на уровне exabytes, прежде чем у вас будет 50% вероятность столкновения ID в одном пространстве приложения.

Ответ 2

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

Я читал, что в соответствии с парадоксальным днем ​​рождения вероятность столкновения UUID составляет 50%, когда генерируется 2 ^ 64 UUID. Теперь 2 ^ 64 - довольно большое число, но вероятность столкновения на 50% кажется слишком рискованной (например, сколько UUID должно существовать до 5% -ной вероятности столкновения - даже если это кажется слишком большой вероятностью).

Проблема с этим анализом двоякая:

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

  • строго говоря, UUID должны быть уникальными среди множества других UUID, с которыми они могут сравниваться. Если вы создаете UUID для использования в качестве ключа базы данных, не имеет значения, если где-то еще в злой альтернативной юниверсе используется тот же UUID для идентификации COM-интерфейса. Точно так же, как это не вызовет путаницы, если кто-то (или что-то еще) назвал "Майкл Берр" на Альфа-Центавра.

Ответ 3

Все имеет ненулевой шанс отказа. Я хотел бы сосредоточиться на гораздо более вероятных проблемах (т.е. Почти все, что вы можете придумать), чем столкновение UUIDs

Ответ 4

Акцент на "разумно" или, как вы выразились, "эффективно": достаточно хорошо, как работает настоящий мир. Объем вычислительной работы, связанной с устранением этого разрыва между "практически уникальным" и "поистине уникальным", огромен. Единственность - это кривая с уменьшающейся отдачей. В какой-то момент на этой кривой существует линия между тем, где "уникально достаточно" по-прежнему доступно, а затем мы кричим ОЧЕНЬ круто. Стоимость добавления уникальности становится довольно большой. Бесконечная уникальность имеет бесконечную стоимость.

UUID/GUID, условно говоря, является простым и быстрым способом генерации идентификатора, который можно разумно считать универсально уникальным. Это очень важно во многих системах, которым необходимо интегрировать данные из ранее несвязанных систем. Например: если у вас есть система управления контентом, которая работает на двух разных платформах, но в какой-то момент нужно импортировать контент из одной системы в другую. Вы не хотите, чтобы идентификаторы менялись, поэтому ваши ссылки между данными из системы A остаются неповрежденными, но вы не хотите столкновения с данными, созданными в системе B. UUID решает это.

Ответ 5

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

Это может помочь в разрешении репликации базы данных и т.д.

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

В любом случае, слово о вероятности столкновения, взятое из Википедии:

Чтобы представить эти цифры в перспективе, один ежегодный риск попасть по метеориту, по оценкам, один шанс в 17 миллиардов, эквивалент с вероятностью создания нескольких десятков триллионов UUID в год и имея один дубликат. Другими словами, только после генерации 1 миллиарда UUID каждую секунду в течение следующих 100 лет, вероятность создания только один дубликат будет около 50%.

Ответ 6

Существует также ненулевая вероятность того, что каждая частица в вашем теле будет одновременно проходить через стул, на котором вы сидите, и вы внезапно окажетесь сидящим на полу.

Вы беспокоитесь об этом?

Ответ 7

Классический пример - это когда вы копируете между двумя базами данных.

DB (A) вставляет запись с int ID 10, и одновременно DB (B) создает запись с идентификатором 10. Это столкновение.

С UUID это не произойдет, поскольку они не совпадут. (почти наверняка)

Ответ 8

Если вы просто посмотрите на альтернативы, например. для простого приложения базы данных, чтобы каждый раз запрашивать базу данных перед созданием нового объекта, вы скоро обнаружите, что использование UUID может эффективно снизить сложность вашей системы. Предоставлено - если вы используете клавиши int, то 32bit, который будет хранить в четверти из 128-битного UUID. Предоставлено - алгоритмы генерации UUID занимают больше вычислительной мощности, чем просто увеличивают число. Но кого это волнует? Накладные расходы на управление "полномочиями" для присвоения уникальных номеров в противном случае легко перевешивают, что на порядки величины, в зависимости от вашего предполагаемого места идентификации уникальности.

Ответ 9

В UUID == ленивый дизайн

Я не согласен с тем, что ты собираешь свои бои. Если дублирующий UUID статистически невозможно, и математика доказана, то зачем беспокоиться? Время разработки затрат вокруг вашей небольшой N UUID-системы генерации нецелесообразно, всегда есть еще дюжина других способов улучшить вашу систему.

Ответ 10

У меня есть схема для исключения UUID. Настройте сервер где-нибудь и сделайте так, чтобы каждый раз, когда часть программного обеспечения запрашивала универсальный уникальный идентификатор, они связывают этот сервер и выталкивают его. Простой!

За исключением того, что с этим существуют некоторые реальные практические проблемы, даже если мы игнорируем откровенную злобу. В частности, этот сервер может выйти из строя или стать недоступным из Интернета. Работа с отказом сервера требует репликации, и это очень сложно сделать правильно (см. Литературу по алгоритму Paxos, почему для построения консенсуса неловко) и довольно медленный. Более того, если все серверы недоступны из определенной части сети, ни один из клиентов, подключенных к этой подсети, не сможет ничего сделать, потому что все они будут ждать новых идентификаторов.

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

Ответ 11

Я не понимаю всех разговоров о вероятности столкновения. Меня не волнует столкновение. Тем не менее, я забочусь о производительности.

https://dba.stackexchange.com/a/119129/33649

UUID - это ошибка производительности для очень больших таблиц. (200K строк не "очень большой".)

Ваш # 3 действительно плохой, когда УСТРОЙСТВО ХАРАКТЕРОВ - utf8 - CHAR (36) занимает 108 байтов!

UUID (GUID) очень "случайны". Используя их как UNIQUE или Приоритетный ключ на больших таблицах очень неэффективен. Это из-за нужно прыгать вокруг таблицы/индекса каждый раз, когда вы вставляете новый UUID или SELECT по UUID. Когда таблица/индекс слишком велика, чтобы соответствовать кешу (см. innodb_buffer_pool_size, который должен быть меньше, чем RAM, обычно 70%), "следующий" UUID может не кэшироваться, следовательно, медленный диск удар. Когда таблица/индекс в 20 раз больше, чем кеш, только 1/20 (5%) хитов - вы привязаны к I/O.

Итак, не используйте UUID, если только

у вас есть "маленькие" таблицы, или вы действительно нуждаетесь в них из-за генерации уникальные идентификаторы из разных мест (и не выяснили другой способ сделать это). Подробнее о UUID: http://mysql.rjweb.org/doc.php/uuid (Это включает функции для преобразования между стандартными 36- char UUID и БИНАРНЫЙ (16).)

Имея как UNIQUE AUTO_INCREMENT, так и UNIQUE UUID в том же стол - это отходы.

Когда происходит INSERT, все уникальные/первичные ключи должны быть проверены для дубликаты. Достаточно одного уникального ключа для требования InnoDB наличия ПЕРВИЧНОГО КЛЮЧА. BINARY (16) (16 байт) несколько громоздкий ( аргумент против того, чтобы сделать это ПК), но не так уж плохо. Объемность когда у вас есть вторичные ключи. InnoDB бесшумно кладет ПК на конец каждого вторичного ключа. Основным уроком здесь является свести к минимуму количество вторичных ключей, особенно для очень больших столы. Для сравнения: INT UNSIGNED - 4 байта с диапазоном 0..4 млрд. BIGINT - 8 байт.

Ответ 12

Используя алгоритм версии 1, кажется, что при ограничении невозможно столкнуться с тем, что из одного и того же MAC-адреса не менее 10 UUID за миллисекунду

Концептуально, оригинал (версия 1) схема генерации UUID была объединить версию UUID с MAC-адрес компьютера, который генерируя UUID, и с помощью число 100-наносекундных интервалов с момента принятия григорианского календарь на Западе. На практике фактический алгоритм более сложный. Эта схема была подвергнута критике в что он недостаточно "непрозрачен"; он показывает как личность компьютер, который сгенерировал UUID и время, в которое оно было сделано.

Кто-то меня исправит, если я неверно истолковал, как это работает.

Ответ 13

Тем, кто говорит, что UUID - плохой дизайн, потому что они могут (по какой-то смехотворной малой вероятности) сталкиваться, в то время как ваши сгенерированные ключи БД не будут... вы знаете вероятность человеческой ошибки, вызвавшую столкновение с вашими ключами, создаваемыми БД, некоторой необъяснимой необходимости является FAR FAR FAR выше, чем вероятность столкновения UUID4. Мы знаем, что если db будет воссоздан, он снова начнет идентификацию в 1, и сколько из нас пришлось воссоздать таблицу, когда мы были уверены, что нам никогда не понадобится? Я поместил свои деньги на безопасность UUID, когда в любой день все начнется неправильно с неизвестными неизвестными.

Ответ 14

На моей последней работе мы получали объекты от третьих сторон, которые были однозначно идентифицированы с помощью UUID. Я поместил таблицу UUID- > long integer lookup и использовал длинные целые числа в качестве моих первичных ключей, потому что это было намного быстрее.

Ответ 15

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

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