Яка ваша думка щодо використання UUID як ідентифікаторів рядків бази даних, особливо у веб-програмах?


78

Я завжди вважав за краще використовувати довгі цілі числа як первинні ключі в базах даних для простоти та (передбачуваної) швидкості. Але коли я використовую схему URL-адрес REST або Rails-подібну для екземплярів об’єктів, я в кінцевому підсумку отримую такі 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 для екземплярів веб-адресних об’єктів? Я думаю, що я все-таки хотів би використовувати цілі стовпці як ПК бази даних лише для пришвидшення приєднання.

Існує також питання про представлення UUID в базі даних. Я знаю, що MySQL зберігає їх як 36-символьні рядки. Здається, Postgres має більш ефективне внутрішнє представлення (128 біт?), Але я сам не пробував. У кого-небудь є досвід із цим?


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

Відповіді:


34

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

Переконайтесь, що ваша база даних підтримує ефективний тип даних для зберігання (16 байт, 128 біт). Щонайменше ви можете закодувати рядок uuid в base64 і використовувати char (22).

Я широко використовував їх із Firebird і рекомендую.


18
base64? Якщо у вас немає власного типу даних для UUID, скиньте тире і вставте байт (32). Можливо, це буде швидше, ніж кодування / декодування до / з base64, коли вам потрібен UUID.
CMircea

29

Наскільки це варте, я бачив тривалу збережену процедуру (понад 9 секунд), яка скорочується до кількох сотень мілісекунд часу виконання, просто переключившись із первинних ключів GUID на цілі числа. Це не означає, що відображення GUID - це погана ідея, але, як зазначали інші, приєднання до них та індексація їх, за визначенням, не буде десь так швидко, як із цілими числами.


1
Якби ви могли надати детальну інформацію про те, де ви це бачили, було б корисно. Розмір БД / таблиць? Бекенд БД? Шаблон доступу (як виглядав запит) ... тощо?
Гарен,

12
Як це взагалі відповідь.
davidahines

16
Це анекдотичні докази, які підтверджують математичну теорію про те, що об’єднання та індексація цілих чисел буде швидшою, ніж довгі (іш) рядки.
Адам Таттл

23

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

Одним із способів як і раніше використовувати GUID та int є наявність у таблиці GUID та INT так, щоб GUID переходило в Int. guide використовується зовні, але int - внутрішньо в БД

наприклад

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

1 та 2 будуть використовуватися в об’єднаннях та інструкціях у веб-програмі. Ця таблиця буде досить вузькою, і запит на неї повинен бути досить швидким


10

Навіщо поєднувати ваш первинний ключ з URI?

Чому б не зробити, щоб ваш ключ URI був зручним для читання (або неможливим для читання, залежно від ваших потреб) і на основі вашого цілого основного індексу, таким чином ви отримуєте найкраще з обох світів. Це робить багато програмного забезпечення для блогів, де відкритий ідентифікатор запису ідентифікується як «куля», а числовий ідентифікатор прихований усередині системи.

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

редагувати: Stackoverflow не зовсім використовує систему, яку я описую, див. коментар Гая нижче.


8
Індекси переповнення стека на ідентифікаторі, а не на кулі. Спробуйте змінити куля вгорі сторінки та натисніть Enter. Він перенаправить вас на канонічну URL-адресу цієї сторінки на основі ідентифікатора (5949) та ігнорує кулі. На сервері він порівнює слизень із збереженим / згенерованим слизнем. Якщо не те саме, він повертає 301. Однак виявляє, що під час пошуку за ідентифікатором (5949).
Гай,

4

Замість таких URL-адрес:

http://example.com/user/783

Чому б не мати:

http://example.com/user/yukondude

Що привітніше для людей і не випускає цієї крихітної інформації?


якщо псевдонім не є унікальним, або, скажімо, назва книги була використана як посилання та змінена - це не добре для SEO та закладок користувачів.
ZiiMakc

4

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


Я не думаю, що метою цього питання було забезпечення безпечного способу використання UUID. Наскільки я зрозумів, що ця тема була практичним наслідком цього рішення. А ваша схема не додає жодної безпеки і марно витрачає цикли процесора!
Патрік Корнеліссен,

4

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


3

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

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

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


Це не застосовується, вам не потрібно показувати uuid в URL-адресі.
davidahines

3
@dah запитатель згадує про використання в URL-адресі запитання.
Brian Lyttle

3

Це також залежить від того, що вам цікаво для вашої заявки. Для додатків n-рівня GUID / UUID простіше реалізувати і їх легше переносити між різними базами даних. Для створення цілочисельних ключів деякі бази даних підтримують об'єкт послідовності спочатку, а деякі вимагають власної побудови таблиці послідовностей.

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


2

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

Хоча це, мабуть, хороша ідея для архітектурної точки зору, це ускладнює щоденну роботу. Іноді виникає потреба робити масові вставки, і наявність UUID ускладнює це, зазвичай вимагаючи написання курсору замість простого оператора SELECT INTO.


2

Я спробував обидва в реальних веб-додатках.

На мою думку, переважно використовувати цілі числа і мати короткі, зрозумілі URL-адреси.

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

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


Дякую за цю думку. Я досліджував використання UUID як первинних ключів з усіма можливими недоліками протягом декількох днів, поки не зрозумів, що єдина перевага (приховування інформації про бізнес) не варта того, у моєму випадку.
Доктор Ян-Філіп Герке

1

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


1

Я думаю, що використання GUID було б кращим вибором у вашій ситуації. Це займає більше місця, але це більш безпечно.


1

Youtube використовує 11 символів із кодуванням base64, яке пропонує 11 ^ 64 можливості, і їх зазвичай досить зручно писати. Цікаво, чи це може запропонувати кращу продуктивність, ніж повна версія UUID. UUID, перетворений на базу 64, буде вдвічі більшим, ніж я вважаю.

Більше інформації можна знайти тут: https://www.youtube.com/watch?v=gocwRvLhDf8


-1

Поки ви використовуєте систему БД з ефективним сховищем, жорсткий диск у наш час і так дешевий ...

Я знаю, що GUID може працювати з деякими часами і надходити з деякими накладними запитами, однак з точки зору безпеки вони є рятівником.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.