Які недоліки використання UUID або GUID в якості основного ключа?


60

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

Які недоліки використання UUID або GUID в якості основного ключа для моїх таблиць?

Можливо, я буду використовувати Derby / JavaDB (на клієнтах) і PostgreSQL (на сервері) як СУБД.


Чому це було б корисно? На які недоліки ви найбільше зосереджені? Відповідь на кожне запитання БД на цю розпливчасту відповідь - це "залежить". Чи можете ви надати більше деталей? Вас найбільше цікавить виконання читання чи записування? про який рівень розповсюдження ми говоримо?
Брайан Балсун-Стентон

@Brian: UUID в розподілених системах є корисним, оскільки ви можете створити первинний ключ для клієнтів і потім завантажити асинхронно дані на сервер. Я здебільшого думаю про недоліки в роботі. Використання багатьох приєднань до UUID не може бути таким хорошим? Наприклад, клієнт додає елемент (UUID, ім'я, постачальник, творець) до інвентарної системи, а потім локальна база даних синхронізується з центральною базою даних на сервері.
Йонас

1
Я думаю, що без більш детальних коментарів з цього приводу, що це буде, як мінімум, "це залежить". Без них я йду на VtC.
jcolebrand

Існує стаття, яка розповідає про вплив GUID проти не-GUID на кластерні індекси на SQL Server, які можуть вам здатися цікавими, навіть якщо це стосується іншого продукту SQL: x.co/Twpp
Jeff

Я помітив, що доктор Derby не перераховує UUID як тип даних. Ви можете розглянути таку альтернативу, як двигун баз даних H2 (чиста база даних Java, як Derby), яка містить список даних даних UUID . Звичайно, Postgres має чудову підтримку для ефективного зберігання , індексації та генерування значень UUID.
Василь Бурк

Відповіді:


29

Це залежить від вашої функції генерації та розміру підсумкових таблиць

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

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

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


3
Чорт засинаєш, ти пішов і дозволив Брайану відповісти на питання. Так, вимога "офлайн-оновлень" повністю змінила всю концепцію там.
jcolebrand

Muahahahaah! :: крутить вуса лихо:
Брайан Балсун-Стентон

1
Навіть при офлайн-написанні можна було б використовувати INT. Наприклад, використовуючи два стовпчики, {Node_ID, Item_ID}де кожен вузол має a Node_ID, і an, Item_IDякий автоматично збільшується на вузол.
Йонас

@Jonas ~ Так, це можливо. Однак одна з причин, чому більшість людей навіть замислюється про GUID, полягає у глобально розділеній реплікації вмісту до інших баз даних. Я маю на увазі, що сам термін є досить QED.
jcolebrand

Що стосується архітектур master / slave або клієнтів з розрідженим з'єднанням + основних архітектур сервера, можливо, можливо використовувати global_id (SERIAL) на master і global_id (BIGINT) + local_id (SERIAL) на ведених. Раби виконують свою локальну роботу, використовуючи local_id та здійснюючи зобов'язання, коли вони можуть спрямовуватися до ведучого, господар отримує дані та надає їм global_id, який він повертає до підлеглому, підлеглий оновлює поле global_id (для використання в довідці у розмові з сервером чи іншим раби).
Михай Станку

22

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

Тепер, якщо ми подивимось на деякі реалізації db: 1.) MySQL - первинні ключі кластеризовані, без можливості змінити поведінку - рекомендувати тут взагалі не використовувати GUID.) Postgres, MS-SQL - ви можете зробити GUID як первинний ключ не кластеризований і використовувати інше поле як кластерний індекс, наприклад, autoincrement int.


Те, що ви пропонуєте для Postgres, можна зробити і в MySQL, з дещо іншою структурою - auto_increment PK (кластерний ключ), GUID з унікальним індексом (без кластера).
ypercubeᵀᴹ

Це не завжди так. Залежно від пропускної здатності дискової системи синхронізація доступу до останньої сторінки може бути вашим вузьким місцем. blog.kejser.org/2011/10/05/…
mwilson

2
"На відміну від Microsoft SQL Server, кластеризація індексу в PostgreSQL не підтримує цей порядок. Вам потрібно повторно застосувати процес CLUSTER для підтримки порядку." Як CLUSTER ON покращує показники показників
bartolo-otrit

Більш скорочена версія інформації @ bartolo-otrit, посилання на: stackoverflow.com/a/4796685/1394393 . Ця відповідь справді не здається мені актуальною, оскільки це питання стосується PG і, здається, передбачає схожість з SQL Server та MySQL, які не існують.
jpmc26

database would need to rearrange all its memory pages to find the right place for insertion=> Я не думаю, що це стосується Postgres, оскільки кластеризація є необов'язковою, а нові рядки зберігаються не упорядкованими.
Флавіен

3

Це залежить.

Серйозно, з усього, що ви давали досі, це приблизно так далеко, як ви можете піти.

Чому було б корисно використовувати UUID? Чому ви не використовуєте INT? Чому ви не зможете пізніше просто індексувати UUID? Ви розумієте, що означає мати відсортований список із ключем UUID та вставити випадковий (не послідовний) UUID через кілька мільйонів рядків?

На якій платформі буде працювати ця платформа? Скільки дисків? Скільки користувачів? Скільки записів?


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

Заява буде написана на Java та клієнтами, якими я користуюся Windows, Mac чи Linux. Клієнти будуть використовувати загальні настільні комп’ютери, які зазвичай мають один диск. Кількість користувачів та записів залежить від того, скільки я отримую клієнтів, але це буде приблизно 5000 на кожного клієнта та клієнта.
Йонас

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