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 MB срещу 15,26 MB)
- 6 неклъстерирани индекса (22,89 MB срещу 91,55 MB)
ОБЩО:25 MB срещу 106 MB - и това е само на една маса!
Още малко храна за размисъл - отлични неща от Кимбърли Трип - прочетете го, прочетете го отново, смилайте го! Това наистина е евангелието за индексиране на SQL Server.
- GUID като ОСНОВЕН КЛЮЧ и/или групиран ключ
- Дебатът за групирания индекс продължава
- Непрекъснато нарастващ ключ за клъстериране - дебатът за клъстерирания индекс..........отново!
- Дисковото пространство е евтино - това е не точката!
Освен ако нямате много добра причина , бих искал да използвам INT IDENTITY
за почти всяка „истинска“ таблица с данни като подразбиране за техния първичен ключ – той е уникален, стабилен е (никога не се променя), тясен е, непрекъснато се увеличава – всички добри свойства които искате да имате в ключ за клъстериране за бърза и надеждна работа на вашите таблици на SQL Server!
Ако имате някаква "естествена" стойност на ключ, която също има всички тези свойства, тогава можете също да използвате това вместо сурогатен ключ. Нодве низове с променлива дължина от макс. 20 знака всеки не отговарят на тези изисквания според мен.