Преимущества и недостатки ключей базы данных GUID / UUID

222

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

Кто-нибудь интенсивно работал с GUID в базе данных? Какие преимущества я получу, пройдя этот путь, и каковы возможные подводные камни?

Мэтт Шеппард
источник
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, что делает ее действительно трудной)
  • ОРМ обычно нравятся им
  • Уникальный для всех приложений. Таким образом, мы можем использовать PK из нашей CMS (guid) в нашем приложении (также guid) и знать, что мы НИКОГДА не получим столкновение.

Недостатки:

  • Большее использование пространства, но пространство дешево (э)
  • Не могу заказать по ID, чтобы получить заказ на вставку.
  • Может показаться уродливым в URL, но на самом деле, WTF вы делаете, вставляя REAL DB ключ в URL !? (Этот момент оспаривается в комментариях ниже)
  • Сложнее делать ручную отладку, но не так сложно.

Лично я использую их для большинства ПК в любой системе приличного размера, но я "обучен" системе, которая была воспроизведена повсеместно, поэтому мы ДОЛЖНЫ иметь их. YMMV.

Я думаю, что дублирование данных - это мусор - вы можете получить дубликаты данных, как бы вы это ни делали. Суррогатные ключи обычно не одобряются, где бы я ни работал. Мы действительно используем WordPress-подобную систему, хотя:

  • уникальный идентификатор для строки (GUID / что угодно). Никогда не виден пользователю.
  • Публичный идентификатор генерируется ОДИН РАЗ из некоторого поля (например, заголовок - сделайте его заголовком статьи)

ОБНОВЛЕНИЕ: Таким образом, это получает + 1 много, и я подумал, что я должен указать на большую обратную сторону GUID PK's: Clustered Indexes.

Если у вас много записей и кластеризованный индекс по GUID, ваша производительность вставки снизится, так как вы вставляете вставки в случайных местах в списке элементов (это точка), а не в конце (что быстро)

Поэтому, если вам нужно вставить производительность, возможно, используйте auto-inc INT и сгенерируйте GUID, если вы хотите поделиться им с кем-то другим (т.е. показать его пользователю в URL)

Ник Мудрый
источник
184
[WTF вы делаете, вставляя РЕАЛЬНЫЙ ключ DB в URL !?] Не уверен, почему это вас беспокоит. Что еще вы бы использовали? Посмотрите на переполнение стека ... У него есть значения IDENTITY в URL повсюду, и он работает просто отлично. Использование ключей БД в 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 между прочим. Очень полезно. Единственное, что мне не хватает - это журнал изменений.
Хенрик Густафссон
3
Я думаю, что этот ответ нуждается в некотором уточнении: это предполагает, что UUID никогда не используются в качестве первичных ключей. Я не знаю, откуда пришло это предположение, но мне еще предстоит увидеть систему, которая не позволяет вам использовать их как таковые. Я знаю, что это старый ответ, я полагаю, что преимущества использования UUID в распределенных системах не были так широко понятны тогда (?).
TNE
12

Почему никто не упоминает производительность? Когда у вас есть несколько объединений, все на основе этих неприятных GUID, производительность будет проходить через этаж, там было :(

Андрей Ринея
источник
1
Можете ли вы уточнить это, как в ситуации, когда мне нужно ввести UUID (или аналогичный), но я обеспокоен использованием их в качестве первичного ключа.
JoeTidee
1
UUID только в 4 раза больше целых чисел ... (если ваша база данных имеет тип UUID)
Jasen
11

Идентификаторы GUID могут доставить вам много хлопот в будущем, если они будут использоваться в качестве «унификаторов», позволяя дублированным данным попадать в ваши таблицы. Если вы хотите использовать GUID, рассмотрите возможность сохранения UNIQUE-ограничений для других столбцов.

Троэльс Арвин
источник
11
Это суть проблемы: введение GUID делает любую строку уникальной. Но не искусственные части строк могут внезапно содержать дубликаты (несколько версий истины).
Троэльс Арвин
8
+1, чтобы компенсировать. Я понимаю, что вы имеете в виду, но это плохо выражено.
Стефано Борини
11

Основным преимуществом является то, что вы можете создавать уникальные идентификаторы без подключения к базе данных. А идентификаторы глобально уникальны, поэтому вы можете легко объединять данные из разных баз данных. Это кажется небольшим преимуществом, но в прошлом я сэкономил много работы.

Основными недостатками являются немного больше места для хранения (не проблема в современных системах), а идентификаторы не очень удобны для чтения человеком. Это может быть проблемой при отладке.

Есть некоторые проблемы с производительностью, такие как фрагментация индекса. Но это легко решаемо (руководство Джимми Ниллсона: http://www.informit.com/articles/article.aspx?p=25862 )

Edit объединил два моих ответа на этот вопрос

@ Matt Sheppard Я думаю, он имеет в виду, что вы можете дублировать строки с разными GUID в качестве первичных ключей. Это проблема любого суррогатного ключа, а не только GUID. И, как он сказал, это легко решается добавлением значимых уникальных ограничений в неключевые столбцы. Альтернатива состоит в том, чтобы использовать естественный ключ, и у них есть реальные проблемы.

Mendelt
источник
Я знаю о гребневых направляющих и тех, которые помогают решить проблему индексации (производительности INSERT). « Основные недостатки - немного больше места для хранения » Повлияет ли это на производительность из-за большого размера файла базы данных?
Амит Джоши
8

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

WIDBA
источник
6

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

Стоимость GUID как первичных ключей (SQL Server 2000)

Мифы, GUID против автоинкремента (MySQL 5)

Это действительно то, что вы хотите.

UID Плюсы

  • Уникальный для каждой таблицы, каждой базы данных, каждого сервера
  • Позволяет легко объединять записи из разных баз данных
  • Позволяет легко распределять базы данных по нескольким серверам
  • Вы можете генерировать идентификаторы где угодно, вместо того, чтобы обращаться к базе данных
  • В большинстве сценариев репликации все равно требуются столбцы GUID

GUID Минусы

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

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

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

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

Антти Хаапала
источник