Переваги та недоліки ключів бази даних GUID / UUID


222

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

Хтось широко працював з GUID в базі даних? Які переваги я отримав би, пішовши таким шляхом, і які ймовірні підводні камені?


1
Джефф опублікував публікацію про це " Основні ключі: ідентифікатори проти GUID ".
jfs

1
також можна використовувати Hi-Lo для віддалених клієнтів: stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm
Ніл МакГуйган


Оновлено місце для публікації Джеффа Етвуда про " Основні ключі: ідентифікатори проти GUID ". Дякую @jfs за довідку.
Адам Кац

@jfs Посилання змінилось на blog.codinghorror.com/primary-keys-ids-versus-guids
cr0ss

Відповіді:


229

Переваги:

  • Може генерувати їх у режимі офлайн.
  • Робить реплікацію тривіальною (на відміну від int's, що робить її РЕАЛЬНО важкою)
  • ORM зазвичай подобаються їм
  • Унікальний для всіх програм. Таким чином, ми можемо використовувати ПК у нашій CMS (guide) у нашому додатку (також настанови) та знаємо, що ми НІКОЛИ не збираємося зіткнутися.

Недоліки:

  • Більше використання космосу, але простір дешевий (ер)
  • Не вдається замовити за ідентифікатором, щоб отримати замовлення на вставку.
  • Може виглядати некрасиво в URL-адресі, але насправді, WTF, ви робите введення реального ключа DB в URL-адресу !? (Цей пункт оспорюється в коментарях нижче)
  • Важче зробити ручну налагодження, але не так важко.

Особисто я використовую їх для більшості ПК у будь-якій системі пристойних розмірів, але я "навчився" на системі, яка реплікується всюди, тому ми маємо їх мати. YMMV.

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

  • унікальний ідентифікатор для рядка (GUID / що завгодно). Ніколи не видно користувачеві.
  • публічний ідентифікатор генерується ОКНЕ з якогось поля (наприклад, заголовок - зробіть це заголовком статті

ОНОВЛЕННЯ: Отже, цей додаток отримує +1 дуже багато, і я подумав, що слід зазначити великий мінус GUID PK: Clustered Indexes.

Якщо у вас багато записів і кластеризований індекс на GUID, продуктивність вашої вставки буде SUCK, оскільки ви отримаєте вставки у випадкових місцях у списку елементів (ось у чому справа), а не в кінці (що швидко)

Тож якщо вам потрібна ефективність вставки, можливо, використовуйте INT з автоматичним включенням і генеруйте GUID, якщо ви хочете поділитися ним з кимось іншим (тобто, показати його користувачеві за URL-адресою)


184
[WTF Ви робите введення реального ключа DB в URL-адресу !?] Не знаєте, чому це вас турбує. Що б ви ще використовували? Подивіться на переповнення стека ... Він має значення IDENTITY в URL-адресі повсюдно, і він працює чудово. Використання ключів DB в URL-адресах не заважає застосовувати захист.
Євро Міцеллі

20
Ні, це не так, але такі речі, як SEO, як правило, краще, якщо в ньому немає ключа - особливо щось таке, як GUID. Звичайно, з цим можна легко обійтись, тому я здогадуюсь, що це було трохи надмірно вираженою заявою
Nic Wise

7
Хороша відповідь, було б непогано, якщо ви також додасте інформацію про недоліки продуктивності використання GUID; наприклад, приєднання, сортування та індексація ними буде повільніше, ніж використання цілих чисел. Посібники фантастичні, але вони коштують, що може бути болем, коли продуктивність є критичною.
Лікар Джонс

26
Майте на увазі одне, люди часто змінюють назви сторінок, запитань, форумів. Для SEO це ДОБРЕ мати щось на зразок невеликого ідентифікатора в URL-адресі, так що якщо змінити назву, Ви все ще знаєте, куди пересилати людей, що надходять зі СТАРОЇ URL-адреси. example.com/35/old-and-bustedщойно став, example.com/35/new-hotnessі ви додаток може просто перевірити заголовок і переслати користувача на 301.
Xeoncross

9
Індексація GUID є дорогою і повільною, що робить їх дійсно поганими кандидатами на первинні ключі.
Меттью Джеймса Девіса

14

@Matt Sheppard:

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

Таким чином, у вас є ідентифікатор клієнта, який однозначно ідентифікує клієнта, і ви переконайтеся, що ідентифікатор відомий замовником (у рахунках-фактурах), щоб клієнт та люди, що обслуговують клієнтів, мали спільну інформацію про те, якщо їм потрібно спілкуватися. Щоб гарантувати відсутність дублюваних записів клієнтів, ви додаєте унікальність-обмеження в таблицю або через первинний ключ на ідентифікаторі клієнта, або через обмеження NOT NULL + UNIQUE у стовпці ідентифікатора клієнта.

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

Деякі "архітектори" можуть сказати вам, що "о, але ми вирішуємо справжнє обмеження унікальності клієнта в нашому рівні додатків!". Правильно. Мода щодо цих мов програмування загального призначення та (особливо) рамок середнього рівня постійно змінюється, і, як правило, ніколи не перетворює вашу базу даних. І є дуже хороший шанс, що вам в якийсь момент вам доведеться отримати доступ до бази даних, не переглядаючи нинішню програму. == Біда. (Але, на щастя, ви і "архітектор" давно пішли, тож ви не будете там, щоб прибирати безлад.) Іншими словами: дотримуйтесь очевидних обмежень у базі даних (і в інших ярусах), також якщо у вас є час).

Іншими словами: Можуть бути вагомі причини для додавання стовпців GUID до таблиць, але, будь ласка, не впадайте у спокусу зробити так, щоб знизити ваші амбіції на узгодженість у реальній (== не GUID) інформації.


1
Почуй чуй! Любіть свою сторінку порівняння SQL btw. Надзвичайно корисний. Єдине, що я сумую, - це журнал змін.
Генрік Густафссон

3
Я думаю, що ця відповідь потребує деякого уточнення: це передбачає, що UUID ніколи не використовуються в якості первинних ключів. Я не знаю, звідки береться це припущення, але я ще не бачив системи, яка не дозволяє використовувати їх як такі. Я знаю, що це стара відповідь, я вважаю, що переваги використання UUID в розподілених системах тоді не були настільки широко зрозумілими (?).
tne

12

Чому ніхто не згадує про ефективність? Коли у вас є декілька приєднань, усі, засновані на цих неприємних GUID, продуктивність буде проходити через підлогу :(


1
Чи можете ви докладно розібратися з цим питанням, коли мені потрібно ввести UUID (або подібне), але я стурбований тим, щоб використовувати їх як первинний ключ.
JoeTidee

1
UUID лише у 4 рази перевищує розмір цілих чисел ... (якщо у вашій базі даних є тип UUID)
Ясен

11

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


11
Це суть проблеми: Введення GUID робить будь-яку рядок унікальним. Але не штучні частини рядків можуть раптом містити дублікати (кілька версій істини).
Тролі Арвін

8
+1 для компенсації Я бачу, що ви маєте на увазі, але це погано виражено.
Стефано Борині

11

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

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

Існують деякі проблеми з продуктивністю, як фрагментація індексу. Але це легко вирішуються (комбіновані посібники від Jimmy Nillson: http://www.informit.com/articles/article.aspx?p=25862 )

Правка злила дві мої відповіді на це запитання

@Matt Sheppard Я думаю, що він означає, що ви можете дублювати рядки з різними GUID в якості первинних ключів. Це проблема з будь-яким сурогатним ключем, а не лише з GUID. І як він сказав, це легко вирішується шляхом додавання значущих унікальних обмежень до не ключових стовпців. Альтернативою є використання природного ключа, у якого виникають реальні проблеми.


Я знаю про комбіновані посібники та ті, які допомагають вирішити проблему індексації (продуктивність INSERT). " Основні недоліки - це трохи більше місця для зберігання ". Це вплине на продуктивність через великий розмір файлу бази даних?
Аміт Джоші

8

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


6

первинні ключі-ідентифікатори проти керівництва

Вартість GUID як первинних ключів (SQL Server 2000)

Міфи, GUID проти автоматичного підвищення (MySQL 5)

Це дійсно те, що ти хочеш.

Плюси UID

  • Унікальний для кожної таблиці, кожної бази даних, кожного сервера
  • Дозволяє легко об’єднувати записи з різних баз даних
  • Дозволяє легкий розподіл баз даних на декількох серверах
  • Ви можете генерувати ідентифікатори де завгодно, замість того, щоб повертатись до бази даних
  • Більшість сценаріїв реплікації так чи інакше потребують стовпців GUID

Мінуси GUID

  • Це колосальне в 4 рази більше, ніж традиційне 4-байтне значення індексу; це може мати серйозні наслідки для продуктивності та зберігання, якщо ви не обережні
  • Громіздкий налагодження (де userid = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Генеровані GUID повинні бути частково послідовними для найкращої продуктивності (наприклад, newsequentialid () у SQL 2005) та для можливості використання кластерних індексів

1

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

RDBM зазвичай забезпечують унікальність первинних ключів і забезпечують пошук за ключем у структурі, званій BTree, що є деревом пошуку з великим коефіцієнтом розгалуження (двійкове дерево пошуку має коефіцієнт розгалуження 2). Тепер послідовний цілочисельний ідентифікатор може призвести до того, що вставки виникатимуть лише на одній стороні дерева, залишаючи більшість вузлів листя недоторканими. Додавання випадкових UUID призведе до розбиття вузлів листів по всьому індексу.

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

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