Каковы причины *не* для использования GUID для первичного ключа?

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

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

Я понимаю, что это никогда не будет самая производительная опция, но откладывающая производительность, я хотел бы знать, существуют ли философские аргументы против этой практики?

На основе ответов позволяют мне разъясниться:

Я говорю о последовательном использовании суррогатного ключа GUID как первичный ключ - независимо от того, ли и как любые естественные или последовательные ключи разработаны на таблице. Это мои предположения:

  1. Целостность данных на основе естественных ключей может быть разработана для, но не предположена.
  2. Функция первичного ключа является ссылочной целостностью, независимо от производительности, упорядочивания или данных.
23
задан Yarin 16 June 2010 в 15:59
поделиться

7 ответов

Джефф Этвуд очень подробно рассказывает об этом:
http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html

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

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

14
ответ дан 29 November 2019 в 01:54
поделиться

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

Я настоятельно рекомендую не делать , так это использовать столбец GUID в качестве ключа кластеризации , что SQL Server делает по умолчанию, если вы специально не укажете ему этого не делать. Основной причиной этого действительно является производительность, которая придет и укусит вас в будущем ... (поверьте мне, это будет лишь вопрос времени), а также пустая трата ресурсов (дисковое пространство и оперативная память в вашем SQL Server машина) чего уж не надо.

Вам действительно нужно разделить две проблемы:

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

2) ключ кластеризации (столбец или столбцы, которые определяют «кластеризованный индекс» в таблице) - это физическая вещь, связанная с хранилищем, и здесь, Маленький, стабильный, постоянно увеличивающийся тип данных - ваш лучший выбор - INT или BIGINT по умолчанию.

По умолчанию первичный ключ в таблице SQL Server также используется в качестве ключа кластеризации, но так быть не должно! Я лично видел значительный прирост производительности при разделении предыдущего первичного / кластерного ключа на основе GUID на два отдельных ключа - первичный (логический) ключ в GUID и ключ кластеризации (упорядочивания) в отдельном INT IDENTITY (1, 1) столбец.

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

Да, я знаю - в SQL Server 2005 и новее есть newsequentialid () , но даже он не является полностью последовательным и, следовательно, страдает теми же проблемами, что и GUID, только немного меньше заметно так.

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

Быстрый расчет - использование INT и GUID в качестве первичного и кластерного ключа:

  • Базовая таблица с 1 000 000 строк (3,8 МБ против 15,26 МБ)
  • 6 некластеризованных индексов (22,89 МБ против 91,55 МБ )

ИТОГО: 25 МБ vs.106 МБ - и это только на одном столе!

Еще немного пищи для размышлений - отличный материал Кимберли Трипп - прочтите, прочтите еще раз, усвойте! На самом деле это евангелие индексации SQL Server.

Марк

16
ответ дан 29 November 2019 в 01:54
поделиться

Вы по-прежнему реализуете естественный ключ каждой таблицы, не так ли? - Очевидно, что сами по себе ключи GUID не предотвратят дублирование данных, избыточность и, как следствие, потерю целостности данных.

Предполагая, что вы применяете другие ключи, добавление идентификаторов GUID к каждой таблице без исключения, вероятно, просто добавляет ненужной сложности и накладных расходов. На самом деле это не упрощает объединение данных в разных таблицах, потому что вам все равно нужно изменить / исключить дубликат другого ключа (ов) таблицы. Я предлагаю вам оценивать использование суррогата GUID в каждом конкретном случае. Наличие общего правила для каждой таблицы не обязательно и не полезно, потому что каждая таблица в конце концов моделирует разные вещи.

4
ответ дан 29 November 2019 в 01:54
поделиться

Простой ответ: это нереляционно.

Запись (как определено идентификатором GUID) может быть уникальной, но нельзя сказать, что ни один из связанных атрибутов уникально встречается с этой записью.

Использование GUID (или любого чисто суррогатного ключа) не более реляционно, чем объявление простого файла реляционным на основании того, что каждую запись можно идентифицировать по номеру строки.

3
ответ дан 29 November 2019 в 01:54
поделиться

Добавление в ewwwn:

Плюсы

  • Это делает практически невозможным для разработчиков «случайно» раскрыть суррогатный ключ пользователям (в отличие от целых чисел, где это происходит почти всегда).
  • На несколько порядков упрощает объединение баз данных по сравнению со столбцами идентификаторов.

Минусы

  • Толстее. Настоящая проблема с тем, что он толще, заключается в том, что он занимает больше места на странице и больше места в ваших индексах, что делает их медленнее. Дополнительное пространство для хранения руководств откровенно неактуально в современном мире.
  • Вы абсолютно должны быть осторожны с тем, как создаются новые ценности. Действительно случайные значения плохо индексируются. Вы вынуждены использовать COMB guid или какой-либо вариант, который добавляет последовательный элемент к guid.
4
ответ дан 29 November 2019 в 01:54
поделиться

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

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

0
ответ дан 29 November 2019 в 01:54
поделиться

Потенциально серьезная причина, о которой часто не думают, заключается в том, что вам, возможно, придется обеспечить совместимость с базой данных Oracle в будущее.

Поскольку Oracle не имеет типа данных столбца uniqueid, это может привести к некоторому кошмару, когда у вас есть два разных типа данных для одного и того же первичного ключа в двух разных базах данных, особенно когда задействована ORM.

1
ответ дан 29 November 2019 в 01:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: