Идентификаторы GUID могут показаться естественным выбором для вашего первичного ключа - и, если вам действительно нужно, вы, вероятно, можете поспорить, чтобы использовать его для ПЕРВИЧНОГО КЛЮЧА таблицы. Что я настоятельно рекомендую не делать, так это использовать столбец GUID в качестве ключа кластеризации , что SQL Server делает по умолчанию, если вы специально не запретите это делать.
Вам действительно нужно держать в стороне две проблемы:
первичный ключ является логической конструкцией - один из ключей - кандидатов , которые однозначно и надежно идентифицируют каждую строку в таблице. Это может быть что угодно, на самом деле - INT
, GUID
, строка - выбрать то , что делает большинство смысла для вашего сценария.
ключ кластеризации (столбец или столбцы , которые определяют «кластерный индекс» на столе) - это физическое хранение связанных вещь, и здесь, небольшой, стабильный, постоянно увеличивающийся тип данных ваш лучший выбор - INT
или BIGINT
как ваш опция по умолчанию.
По умолчанию первичный ключ в таблице SQL Server также используется в качестве ключа кластеризации, но это не обязательно должно быть так! Я лично видел значительное увеличение производительности, когда разбивал предыдущий основанный на GUID первичный / кластерный ключ на два отдельных ключа - первичный (логический) ключ в GUID и ключ кластеризации (упорядочения) в отдельном INT IDENTITY(1,1)
столбце.
Как Кимберли Трипп, королева индексации, и многие другие неоднократно заявляли, 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.
PS: конечно, если вы имеете дело с несколькими сотнями или несколькими тысячами строк - большинство из этих аргументов не окажут большого влияния на вас. Однако: если вы попадаете в десятки или сотни тысяч строк или начинаете считать в миллионах - тогда эти точки становятся очень важными и очень важными для понимания.
Обновление: если вы хотите, чтобы ваш PKGUID
столбец был вашим основным ключом (но не ключом кластеризации), а другой столбец MYINT
( INT IDENTITY
) - вашим ключом кластеризации - используйте это:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
По сути: вам просто нужно явно указать PRIMARY KEY
ограничению, что оно NONCLUSTERED
(в противном случае оно создается как кластерный индекс по умолчанию), а затем вы создаете второй индекс, который определяется какCLUSTERED
Это будет работать - и это допустимый вариант, если у вас есть существующая система, которую необходимо «перепроектировать» для повышения производительности. Для новой системы, если вы начинаете с нуля и у вас нет сценария репликации, я бы всегда выбирал в ID INT IDENTITY(1,1)
качестве своего кластерного первичного ключа - гораздо более эффективный, чем все остальное!