GUID
kan tyckas vara ett naturligt val för din primärnyckel - och om du verkligen måste, kan du antagligen argumentera för att använda den för tabellens PRIMÄRNYCKEL. Vad jag starkt rekommenderar att inte gör använder GUID
kolumnen som klustringsnyckel , vilket SQL Server gör som standard, om du inte specifikt säger åt den att inte göra det.
Du måste verkligen hålla isär två frågor:
-
den primära nyckeln är en logisk konstruktion - en av kandidatnycklarna som unikt och tillförlitligt identifierar varje rad i din tabell. Det här kan vara vad som helst - en
INT
, enGUID
, en sträng - välj det som är mest meningsfullt för ditt scenario. -
klustringsnyckeln (kolumnen eller kolumnerna som definierar det "klustrade indexet" i tabellen) - detta är en fysisk lagringsrelaterad sak, och här är en liten, stabil, ständigt ökande datatyp ditt bästa val -
INT
ellerBIGINT
som ditt standardalternativ.
Som standard används primärnyckeln på en SQL Server-tabell också som klustringsnyckel - men det behöver inte vara så! Jag har personligen sett enorma prestandavinster när jag delar upp den tidigare GUID-baserade primära/klustrade nyckeln i två separata nycklar - den primära (logiska) nyckeln på GUID
, och klustringsnyckeln (beställning) på en separat INT IDENTITY(1,1)
kolumn.
Som Kimberly Tripp
- indexeringens drottning - och andra har sagt väldigt många gånger - en GUID
eftersom klustringsnyckeln inte är optimal, eftersom den på grund av dess slumpmässighet kommer att leda till massiv sida- och indexfragmentering och till allmänt dålig prestanda.
Ja, jag vet - det finns newsequentialid()
i SQL Server 2005 och uppåt - men även det är inte riktigt och helt sekventiellt och lider därmed också av samma problem som GUID
- bara lite mindre framträdande så.
Sedan finns det en annan fråga att tänka på:klustringsnyckeln på ett bord kommer att läggas till varje post på varje icke-klustrade index på ditt bord också - så du vill verkligen se till att den är så liten som möjligt. Vanligtvis en INT
med 2+ miljarder rader borde vara tillräckligt för de allra flesta tabeller - och jämfört med en GUID
som klustringsnyckel kan du spara hundratals megabyte lagringsutrymme på disk och i serverminne.
Snabb beräkning - med INT
kontra GUID
som primär nyckel och klustringsnyckel:
- Bastabell med 1 000 000 rader (3,8 MB mot 15,26 MB)
- 6 icke-klustrade index (22,89 MB mot 91,55 MB)
TOTALT:25 MB kontra 106 MB - och det är bara på ett enda bord!
Lite mer tankeställare - utmärkta grejer av Kimberly Tripp - läs det, läs det igen, smält det! Det är verkligen SQL Server-indexeringsevangeliet.
- GUID:er som PRIMÄRNYCKEL och/eller klustrad nyckel
- Debatten om klustrade index fortsätter
- Ständigt ökande klustringsnyckel - The Clustered Index Debate...........igen!
- Diskutrymme är billigt - det är inte poängen!
Om du inte har en mycket god anledning , jag skulle hävda att man använder en INT IDENTITY
för nästan varje "riktig" datatabell som standard för deras primärnyckel - den är unik, den är stabil (förändras aldrig), den är smal, den ökar hela tiden - alla bra egenskaper som du vill ha i en klustringsnyckel för snabb och pålitlig prestanda för dina SQL Server-tabeller!
Om du har något "naturligt" nyckelvärde som också har alla dessa egenskaper, kan du också använda det istället för en surrogatnyckel. Men två strängar med variabel längd på max. 20 tecken vardera uppfyller inte de kraven enligt mig.