Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Uniqueidentifier срещу ИДЕНТИЧНОСТ срещу материален код -- кой е най-добрият избор за първичен ключ?

GUID може да изглежда като естествен избор за вашия първичен ключ - и ако наистина трябва, вероятно бихте могли да спорите да го използвате за ПЪРВИЧЕН КЛЮЧ на таблицата. Какво силно бих препоръчал да не правите е да използвате GUID като ключ за клъстериране , което SQL Server прави по подразбиране, освен ако изрично не му кажете да не го прави.

Наистина трябва да отделите два проблема:

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

  2. ключът за групиране (колоната или колоните, които определят „клъстерирания индекс“ в таблицата) – това е физическо нещо, свързано със съхранението, и тук най-добрият избор е малък, стабилен, непрекъснато нарастващ тип данни - 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.

Освен ако нямате много добра причина , бих искал да използвам INT IDENTITY за почти всяка „истинска“ таблица с данни като подразбиране за техния първичен ключ – той е уникален, стабилен е (никога не се променя), тясен е, непрекъснато се увеличава – всички добри свойства които искате да имате в ключ за клъстериране за бърза и надеждна работа на вашите таблици на SQL Server!

Ако имате някаква "естествена" стойност на ключ, която също има всички тези свойства, тогава можете също да използвате това вместо сурогатен ключ. Нодве низове с променлива дължина от макс. 20 знака всеки не отговарят на тези изисквания според мен.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. острови и пропуски tsql

  2. mssql php не може да избере тип поле nvarchar(MAX)

  3. Обединени колони вертикално в SQL

  4. Как да получа правилна среднопретеглена дата в SQL

  5. Ескейпиране на низове, съдържащи единични кавички в PowerShell, готово за SQL заявка