2009-07-21 2 views
3

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

Вопрос: Должен ли я использовать GUID в качестве основного ключа во всех таблицах во все времена на всякий случай, если мне понадобится эта возможная масштабируемость по дороге? Это делает мою схему более гибкой в ​​том, что она может быть перенесена между платформами во все времена? Помогает ли это поддерживать гибкость моего ORM (независимо от вкуса), не встраивая специфические функции платформы?

Ответы:

@David Archer: За свой комментарий, я обновил свой пост, чтобы не сказать "естественный ключ". Правильны ли вы в этом естественном ключе как such. Спасибо за исправление.

+0

Просто ничто, ваша терминология кажется немного выключенной. «Естественный ключ» обычно основан на чем-то определенном для записи типа, которую вы описываете, и считается уникальным и неизменным. Подумайте о номере социального страхования для хранения списка граждан США или адреса электронной почты для списка пользователей. Термин, который вы ищете, является суррогатным ключом, и он одинаково применим как к автогенерированным ints, так и к GUID. –

ответ

4

Я предпочитаю первичные ключи, созданные приложением, обычно используя алгоритм lo/hi, реализованный NHibernate (когда я использую его в проекте). В противном случае последовательные GUID работают так же хорошо. Это не только мой совет, но и several люди who have делали эту вещь в области развития намного дольше, чем я.

Проблема, которую я вижу с использованием первичных ключей сгенерированных БД, заключается в том, что вам нужно ударить по базе данных, чтобы получить эти значения идентичности по сравнению с тем, что все настроено, прежде чем вы сохраняете ее в базе данных. Из-за этого он обычно ломает структуру «Единицы работы» в NHibernate. Если вы не используете шаблон UoW в своем приложении, то, очевидно, этот недостаток не применяется.

Если вы используете GUID для своего ПК, вы обязательно захотите использовать последовательные GUID для устранения фрагментации индекса. Это также дает вам «грубый порядок сортировки», который упоминается в другом плакате, хотя обычно у меня был столбец DateInserted или аналогичный для этих типов вещей.

Объединив столбец GUID has been shown с минимальными эксплуатационными издержками по сравнению с вашим 4-байтовым целым, и я бы рискнул сказать, что для не больших наборов данных разница в производительности тривиальна.

Природные ключи - это икру дьявола. :)

+2

+1 - икра дьявола !!! Хороший ответ. –

1

Я был сожжен слишком много раз, когда «естественные ключи» менялись или дублировались, чтобы когда-либо рассматривать их использование. Мое решение о том, использовать ли последовательности или GUID для ключей, определяется тем, ожидаю ли я когда-либо читать или говорить на одном из них.

+0

Последовательности имеют недостаток, который можно угадать. Таким образом, кто-то может редактировать URL-адрес, чтобы увидеть, какую запись он возвращает. –

+1

Если кто-то может перейти на запрещенные страницы путем редактирования URL-адресов, ваша защита доступа нарушена. Использование GUID не решит проблему. –

3

Возможно, вы не должны использовать необработанные GUID в качестве основного ключа. Это приводит к существенной фрагментации ваших данных. SQL Server имеет function, чтобы дать вам «последовательное руководство», чтобы помочь смягчить эту проблему. В этом разделе подробно обсуждается эта проблема here. Еще одним прекрасного обсуждением этого here ...

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

+0

В ответе выше значение Guid не попадает в базу данных, но если функция генерации последовательного указателя является функцией t-sql, вы по-прежнему нажимаете на базу данных. Если вы рекомендуете последовательный указатель, и для этого требуется удар db, почему бы просто не попасть в БД и получить порядковый номер. –

1

У меня не было большого опыта работы с этим, но с помощью GUID для присоединения заставляет меня съеживаться. 4 байт против 36 кажется icky.

Однако я начал использовать GUID как публичные идентификаторы, а не сами поля идентичности. Взгляните на URL выше, 1156712. Если по какой-то причине SO пришлось объединить с другим подобным приложением (скажем, SU), эти идентификаторы вопросов столкнулись бы с одним или другим, ему пришлось бы изменить URL-адрес, испортивший любые жестко закодированные ссылки и, возможно, статистика google. В то время как если каждый элемент был публично идентифицирован, это использование GUID, а внутренние объединения использовали поля int или bigint, в которых вы могли бы использовать лучшее из обоих миров.

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

+2

GUID - 32 шестнадцатеричных символа == 16 байт, а не 36. :) –

2

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

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

Что касается фрагментации, рассмотрите также стоимость дискового пространства. Если вам будет меньше 10 000 строк (в таблице), это, вероятно, не является большой проблемой, но если ваша система должна поддерживать более 10 000 строк (в таблице), вы обнаружите, что производительность и дисковое хранилище (и разграничение индекса) лучше обслуживается использованием Big Ints (большие целые числа) + identity (autonumber), которые хорошо масштабируются до объема.

Я бы вообще избегал естественных ключей - даже риск изменения логики вокруг них делает его слишком рискованным ИМХО (например, если они внезапно становятся неединственными).

2

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

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

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

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

Лучшее обсуждение основных/кластеризованных индексов и идентификаторов GUID, о которых я знаю, это пара статей Ким Трипп, Королевы индексирования на земле SQL Server - проверьте их!

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

Marc

Смежные вопросы