Подтвердить что ты не робот

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

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

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

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

Основываясь на ответах, позвольте мне пояснить:

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

  • Целостность данных, основанная на естественных ключах, может быть разработана, но не предполагается.
  • Функция первичного ключа - это ссылочная целостность, независимо от производительности, последовательности или данных.
4b9b3361

Ответ 1

Джефф Этвуд рассказывает об этом очень подробно:
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) и для включения кластеризованных индексов

Ответ 2

GUID могут показаться естественным выбором для вашего основного ключа - и, если вы действительно должны, вы, вероятно, можете поспорить, чтобы использовать его для ПЕРВИЧНОГО КЛЮЧА таблицы.

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

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

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

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

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

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

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

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

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

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

ВСЕГО: 25 МБ против 106 МБ - и это только на одной таблице!

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

Марк

Ответ 3

Добавление к эвору:

Доводы

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

против

  • Fatter. Реальная проблема с тем, что она более живая, состоит в том, что она потребляет больше места на странице и больше места в ваших индексах, что делает их медленнее. Дополнительное пространство для хранения Guids откровенно не имеет отношения к сегодняшнему миру.
  • Вы абсолютно должны быть осторожны в создании новых значений. Поистине случайные значения хорошо не индексируются. Вы вынуждены использовать COMB guid или какой-либо вариант, который добавляет последовательный элемент в guid.

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

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

Ответ 7

Интересно, почему нет стандартного типа miniGUID? Казалось бы, выполнение достойного хэша по GUID должно дать 64-битное число, которое будет иметь тривиальную вероятность дублирования в любой вселенной, в которой нет миллиарда или более вещей. Поскольку юниверс, в котором используются большинство идентификаторов GUID/miniGUID, никогда не будет расти больше миллиона вещей, а тем более миллиарда, я бы подумал, что меньший 8-байтовый miniGuid будет очень полезен.

Это, конечно же, не предполагает, что он должен использоваться как кластеризованный индекс; что значительно затруднит работу. Тем не менее, 8-байтовый miniGUID будет тратить только третье место полного GUID (по сравнению с 4-байтным индексом).

Ответ 8

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

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