sql >> Databasteknik >  >> RDS >> Sqlserver

Uniqueidentifier vs. IDENTITY vs. Material Code --vilket är det bästa valet för primärnyckel?

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:

  1. 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 , en GUID , en sträng - välj det som är mest meningsfullt för ditt scenario.

  2. 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 eller BIGINT 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.

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.



  1. Hur analyserar jag objektdata från MySQL-databasen med PHP PDO?

  2. Kontrollera om match 3 eller fler matchar i DB-raden

  3. Postgresql-uppdatering med join

  4. Transponera i SQL Server 2012