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

Я всегда предпочитал использовать длинные целые числа в качестве первичных ключей в базах данных, для простоты и (предполагаемой) скорости. Но при использовании REST или 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 для веб-адресов объектов? Я думаю, что я все же хотел бы использовать целые столбцы в качестве базы данных PK только для ускорения объединений.

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


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

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

например

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

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

Ответ 4

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

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

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

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

Ответ 5

Вместо URL-адресов, подобных этому:

http://example.com/user/783

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

http://example.com/user/yukondude

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

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

Ответ 9

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

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

Ответ 10

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

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

Ответ 11

Я пробовал как в реальных веб-приложениях.

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

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

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

Ответ 12

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

Ответ 13

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

Ответ 14

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

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

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