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

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

Ответы [ 15 ]

32 голосов
/ 08 августа 2008

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

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

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

28 голосов
/ 08 августа 2008

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

23 голосов
/ 08 августа 2008

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

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

например

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

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

9 голосов
/ 16 сентября 2008

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

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

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

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

4 голосов
/ 13 августа 2008

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

4 голосов
/ 12 августа 2008

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

4 голосов
/ 08 августа 2008

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

http://example.com/user/783

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

http://example.com/user/yukondude

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

3 голосов
/ 16 сентября 2008

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

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

3 голосов
/ 08 августа 2008

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

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

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

2 голосов
/ 02 октября 2013

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

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

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

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

...