sql >> Database >  >> RDS >> Sqlserver

Uniqueidentifier versus IDENTITEIT versus materiaalcode - wat is de beste keuze voor de primaire sleutel?

GUID lijkt misschien een natuurlijke keuze voor je primaire sleutel - en als het echt moet, zou je waarschijnlijk kunnen argumenteren om het te gebruiken voor de PRIMAIRE SLEUTEL van de tabel. Wat ik sterk zou aanraden niet te doen is gebruik maken van de GUID kolom als de clustersleutel , wat SQL Server standaard doet, tenzij u specifiek aangeeft dat niet te doen.

Je moet echt twee zaken uit elkaar houden:

  1. de primaire sleutel is een logische constructie - een van de kandidaatsleutels die elke rij in uw tabel op unieke en betrouwbare wijze identificeert. Dit kan werkelijk van alles zijn - een INT , een GUID , een string - kies wat het meest logisch is voor uw scenario.

  2. de clustersleutel (de kolom of kolommen die de "geclusterde index" in de tabel definiëren) - dit is een fysiek opslaggerelateerd ding, en hier is een klein, stabiel, steeds groter wordend gegevenstype de beste keuze - INT of BIGINT als uw standaardoptie.

Standaard wordt de primaire sleutel op een SQL Server-tabel ook gebruikt als de clustersleutel - maar dat hoeft niet zo te zijn! Ik heb persoonlijk enorme prestatieverbeteringen gezien bij het opsplitsen van de vorige op GUID gebaseerde primaire / geclusterde sleutel in twee afzonderlijke sleutels - de primaire (logische) sleutel op de GUID , en de clustering (bestellen) sleutel op een aparte INT IDENTITY(1,1) kolom.

Als Kimberly Tripp - de Koningin van Indexeren - en anderen hebben heel vaak aangegeven - een GUID omdat de clustersleutel niet optimaal is, omdat deze vanwege zijn willekeur tot massale pagina- en indexfragmentatie en tot over het algemeen slechte prestaties leidt.

Ja, ik weet het - er is newsequentialid() in SQL Server 2005 en hoger - maar zelfs dat is niet echt en volledig sequentieel en heeft dus ook last van dezelfde problemen als de GUID - alleen iets minder opvallend.

Dan is er nog een ander probleem om te overwegen:de clustersleutel op een tabel wordt ook toegevoegd aan elk item op elke niet-geclusterde index op uw tabel - dus u wilt er zeker van zijn dat deze zo klein mogelijk is. Meestal is een INT met 2+ miljard rijen zou voldoende moeten zijn voor de overgrote meerderheid van tabellen - en vergeleken met een GUID als clustersleutel kun je jezelf honderden megabytes aan opslagruimte besparen op schijf en in het servergeheugen.

Snelle berekening - met behulp van INT vs. GUID als primaire en clustersleutel:

  • Basistabel met 1.000.000 rijen (3,8 MB vs. 15,26 MB)
  • 6 niet-geclusterde indexen (22,89 MB versus 91,55 MB)

TOTAAL:25 MB versus 106 MB - en dat is slechts op een enkele tafel!

Nog wat stof tot nadenken - uitstekende dingen van Kimberly Tripp - lees het, lees het opnieuw, verwerk het! Het is eigenlijk het SQL Server-indexeringsevangelie.

Tenzij je een zeer goede reden hebt , zou ik willen pleiten voor het gebruik van een INT IDENTITY voor bijna elke "echte" gegevenstabel als de standaard voor hun primaire sleutel - het is uniek, het is stabiel (verandert nooit), het is smal, het wordt steeds groter - alle goede eigenschappen die u in een clustersleutel wilt hebben voor snelle en betrouwbare prestaties van uw SQL Server-tabellen!

Als je een "natuurlijke" sleutelwaarde hebt die ook al die eigenschappen heeft, dan zou je die ook kunnen gebruiken in plaats van een surrogaatsleutel. Maar twee snaren met variabele lengte van max. 20 tekens elk voldoen naar mijn mening niet aan die vereisten.



  1. Oracle :Select distinct werkt niet wanneer de cursor binnen een cursor staat (met behulp van cursorexpressie)

  2. Bewaar tijd tussen records

  3. Hoe Top with Ties te gebruiken in SQL Server - SQL Server / TSQL Tutorial Part 114

  4. Mijn programma kan geen waarden opslaan in MySQL met behulp van mysql connector lib in Python