Каково ваше мнение об использовании UUID в качестве идентификаторов строк базы данных, особенно в веб-приложениях?

StackOverflow https://stackoverflow.com/questions/5949

  •  08-06-2019
  •  | 
  •  

Вопрос

Я всегда предпочитал использовать длинные целые числа в качестве первичных ключей в базах данных, для простоты и (предполагаемой) скорости.Но при использовании ОТДЫХ или Rails-подобная схема URL-адресов для экземпляров объектов, тогда я бы получил такие URL-адреса, как этот:

http://example.com/user/783

И тогда предполагается, что есть также пользователи с идентификаторами 782, 781, ..., 2 и 1.Предполагая, что рассматриваемое веб-приложение достаточно безопасно, чтобы люди не могли вводить другие номера для просмотра других пользователей без авторизации, простой последовательно назначаемый суррогатный ключ также "пропускает" общее количество экземпляров (старше этого), в данном случае пользователей, которые могут представлять собой привилегированную информацию.(Например, я являюсь пользователем #726 в stackoverflow.)

Был бы UUID/GUID может быть лучшим решением?Тогда я мог бы настроить URL-адреса следующим образом:

http://example.com/user/035a46e0-6550-11dd-ad8b-0800200c9a66

Не совсем лаконично, но на дисплее меньше подразумеваемой информации о пользователях.Конечно, это попахивает "безопасностью через неизвестность", которая не заменяет должной безопасности, но кажется, по крайней мере, немного более безопасной.

Стоит ли это преимущество затрат и сложности реализации UUID для экземпляров объектов с веб-адресом?Я думаю, что я бы все равно хотел использовать целочисленные столбцы в качестве PKS базы данных просто для ускорения соединений.

Существует также вопрос о представлении UUID в базе данных.Я знаю, что MySQL хранит их в виде 36-символьных строк.Postgres, похоже, имеет более эффективное внутреннее представление (128 бит?) но я сам его не пробовал.У кого-нибудь есть какой-нибудь опыт в этом?


Обновить:для тех, кто спрашивал о простом использовании имени пользователя в URL (например, http://example.com/user/yukondude), это прекрасно работает для экземпляров объектов с уникальными именами, но как насчет миллионов объектов веб-приложений, которые на самом деле можно идентифицировать только по номеру?Заказы, транзакции, счета-фактуры, повторяющиеся названия изображений, вопросы stackoverflow, ...

Это было полезно?

Решение

Я не могу ничего сказать о веб-стороне вашего вопроса.Но uuid отлично подходят для n-уровневых приложений.Генерация ПК может быть децентрализована:каждый клиент генерирует свой собственный пк без риска столкновения.И разница в скорости, как правило, невелика.

Убедитесь, что ваша база данных поддерживает эффективный тип данных для хранения (16 байт, 128 бит).По крайней мере, вы можете закодировать строку uuid в base64 и использовать char(22) .

Я широко использовал их с Firebird и действительно рекомендую.

Другие советы

Как бы то ни было, я видел, как время выполнения длительной хранимой процедуры (более 9 секунд) сократилось всего до нескольких сотен миллисекунд, просто переключившись с первичных ключей GUID на целые числа.Этого нельзя сказать отображение GUID - плохая идея, но, как указывали другие, объединение с ними и их индексация, по определению, будет происходить далеко не так быстро, как с целыми числами.

Я могу ответить вам, что в SQL server, если вы используете тип данных uniqueidentifier (GUID) и используете функцию NEWID () для создания значений, вы получите ужасную фрагментацию из-за разделения страниц.Причина в том, что при использовании NEWID() генерируемое значение не является последовательным.SQL 2005 добавил функцию NEWSEQUANTIAL (), чтобы исправить это

Один из способов по-прежнему использовать GUID и int - это иметь guid и int в таблице, чтобы guid соответствовал int.guid используется извне, а int - внутри базы данных

например

457180FB-C2EA-48DF-8BEF-458573DA1C10    1
9A70FF3C-B7DA-4593-93AE-4A8945943C8A    2

1 и 2 будут использоваться в объединениях и идентификаторах guid в веб-приложении.Эта таблица будет довольно узкой, и запрос к ней должен выполняться довольно быстро

Зачем связывать ваш первичный ключ с вашим URI?

Почему бы не сделать так, чтобы ваш ключ URI был удобочитаемым человеком (или не поддающимся угадыванию, в зависимости от ваших потребностей), а ваш основной индекс основывался на целых числах, таким образом, вы получите лучшее из обоих миров.Многие программы для блогов делают это, когда открытый идентификатор записи идентифицируется с помощью "slug", а числовой идентификатор скрыт внутри системы.

Дополнительным преимуществом здесь является то, что теперь у вас действительно хорошая структура URL, что хорошо для SEO.Очевидно, что для транзакции это не очень хорошо, но для чего-то вроде stackoverflow это важно (см. URL вверху ...).Добиться уникальности не так уж и сложно.Если вы действительно обеспокоены, сохраните хэш slug где-нибудь внутри таблицы и выполните поиск перед вставкой.

Редактировать: Stackoverflow не совсем использует систему, которую я описываю, смотрите Комментарий Гая ниже.

Вместо таких URL-адресов, как этот:

http://example.com/user/783

Почему бы и нет:

http://example.com/user/yukondude

Что более дружелюбно по отношению к людям и не допускает утечки такой крошечной информации?

Вы могли бы использовать целое число, которое связано с номером строки, но не является последовательным.Например, вы могли бы взять 32 бита последовательного идентификатора и переставить их по фиксированной схеме (например, бит 1 становится битом 6, бит 2 становится битом 15 и т.д.).
Это будет двунаправленное шифрование, и вы будете уверены, что два разных идентификатора всегда будут иметь разное шифрование.
Очевидно, что это было бы легко расшифровать, если потратить время на генерацию достаточного количества идентификаторов и получение схемы, но, если я правильно понимаю вашу проблему, вы просто хотите не выдавать информацию слишком легко.

Мы используем GUID в качестве первичных ключей для всех наших таблиц, поскольку он удваивается как RowGUID для репликации MS SQL Server.Это очень упрощает задачу, когда клиент внезапно открывает офис в другой части мира...

Я не думаю, что GUID дает вам много преимуществ.Пользователи ненавидят длинные, непонятные URL-адреса.

Создайте более короткий идентификатор, который можно сопоставить с URL-адресом, или примените соглашение об уникальном имени пользователя (http://example.com/user/brianly).Ребята из 37Сигналы вероятно, я бы посмеялся над вами за то, что вы беспокоитесь о чем-то подобном, когда речь заходит о веб-приложении.

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

Это также зависит от того, что вас интересует в вашем приложении.Для n-уровневых приложений идентификаторы GUID / UUID проще реализовать и их легче переносить между различными базами данных.Для создания целочисленных ключей некоторые базы данных поддерживают объект sequence изначально, а некоторые требуют пользовательского построения таблицы sequence.

Целочисленные ключи, вероятно (у меня нет чисел), обеспечивают преимущество в производительности запросов и индексации, а также в использовании пространства.Прямой запрос к базе данных также намного проще с помощью цифровых клавиш, меньше копирования / вставки, так как их легче запомнить.

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

Хотя это, вероятно, хорошая идея с архитектурной точки зрения, с ней сложно работать на ежедневной основе.Иногда возникает необходимость выполнять массовые вставки, и наличие UUID делает это очень сложным, обычно требуя ввода курсора вместо простого оператора SELECT INTO.

Я пробовал и то, и другое в реальных веб-приложениях.

Мое мнение таково, что предпочтительнее использовать целые числа и иметь короткие, понятные URL-адреса.

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

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

Я думаю, что это один из тех вопросов, которые вызывают квазирелигиозные дебаты, и говорить о нем почти бесполезно.Я бы просто сказал, используйте то, что вы предпочитаете.В 99% систем не имеет значения, какой тип ключа вы используете, поэтому преимущества (указанные в других сообщениях) использования одного вида по сравнению с другим никогда не будут проблемой.

Я думаю, что использование GUID было бы лучшим выбором в вашей ситуации.Это занимает больше места, но при этом более безопасно.

Youtube использует 11 символов в кодировке base64, которая предлагает возможности 11 ^ 64, и их обычно довольно легко записать.Интересно, обеспечит ли это лучшую производительность, чем полный UUID.UUID, преобразованный в базовый 64, будет вдвое больше, чем я полагаю.

Более подробную информацию можно найти здесь: https://www.youtube.com/watch?v=gocwRvLhDf8

Пока вы используете систему баз данных с эффективным хранилищем, жесткий диск в любом случае в наши дни стоит дешево...

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

Думая о безопасности через неясность, они хорошо подходят при формировании неясных URI и создании нормализованных БД с безопасностью, определенной таблицей, записью и столбцом. вы не можете ошибиться с GUID, попробуйте сделать это с идентификаторами на основе целых чисел.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top