sql >> Database teknologi >  >> RDS >> Sqlserver

Uniqueidentifier vs. IDENTITY vs. Material Code - hvilket er det bedste valg for primær nøgle?

GUID kan synes at være et naturligt valg for din primære nøgle - og hvis du virkelig skal, kan du sikkert argumentere for at bruge den til den primære nøgle i tabellen. Hvad jeg kraftigt vil anbefale ikke at gøre er at bruge GUID kolonne som klyngenøgle , hvilket SQL Server gør som standard, medmindre du specifikt fortæller den ikke at gøre det.

Du skal virkelig holde to problemer adskilt:

  1. den primære nøgle er en logisk konstruktion - en af ​​kandidatnøglerne, der unikt og pålideligt identificerer hver række i din tabel. Dette kan være hvad som helst - en INT , en GUID , en streng - vælg det, der giver mest mening for dit scenarie.

  2. klyngerøglen (den eller de kolonner, der definerer "klyngeindekset" i tabellen) - dette er en fysisk lagringsrelateret ting, og her er en lille, stabil, stadigt stigende datatype dit bedste valg - INT eller BIGINT som din standardindstilling.

Som standard bruges den primære nøgle på en SQL Server-tabel også som klyngenøgle - men sådan behøver det ikke at være! Jeg har personligt set massive præstationsgevinster ved at opdele den tidligere GUID-baserede primære/klyngede nøgle i to separate nøgler - den primære (logiske) nøgle på GUID , og clustering (ordre) nøglen på en separat INT IDENTITY(1,1) kolonne.

Som Kimberly Tripp - Dronningen af ​​indeksering - og andre har udtalt rigtig mange gange - en GUID da klyngingsnøglen ikke er optimal, da den på grund af dens tilfældighed vil føre til massiv side- og indeksfragmentering og generelt dårlig ydeevne.

Ja, jeg ved det - der er newsequentialid() i SQL Server 2005 og nyere - men selv det er ikke rigtig og fuldt sekventielt og lider dermed også af de samme problemer som GUID - bare en smule mindre fremtrædende.

Så er der et andet problem at overveje:klyngingsnøglen på et bord vil også blive tilføjet til hver eneste indgang på hvert ikke-klyngede indeks på din tabel - så du vil virkelig gerne sikre dig, at den er så lille som muligt. Typisk en INT med 2+ milliarder rækker burde være tilstrækkeligt til langt de fleste tabeller - og sammenlignet med en GUID som klyngenøgle kan du spare dig selv for hundredvis af megabyte lagerplads på disk og i serverhukommelse.

Hurtig beregning - ved hjælp af INT vs. GUID som primær og klyngenøgle:

  • Basistabel med 1.000.000 rækker (3,8 MB vs. 15,26 MB)
  • 6 ikke-klyngede indekser (22,89 MB vs. 91,55 MB)

TOTAL:25 MB vs. 106 MB - og det er bare på et enkelt bord!

Lidt mere stof til eftertanke - fremragende ting af Kimberly Tripp - læs det, læs det igen, fordøj det! Det er virkelig SQL Server-indekseringsevangeliet.

Medmindre du har en meget god grund , vil jeg påstå at bruge en INT IDENTITY for næsten hver "rigtig" datatabel som standard for deres primære nøgle - den er unik, den er stabil (ændrer sig aldrig), den er smal, den er stadig stigende - alle de gode egenskaber som du vil have i en klyngenøgle for hurtig og pålidelig ydeevne af dine SQL Server-tabeller!

Hvis du har en "naturlig" nøgleværdi, der også har alle disse egenskaber, kan du måske også bruge den i stedet for en surrogatnøgle. Men to strenge med variabel længde på max. 20 tegn hver opfylder ikke disse krav efter min mening.



  1. Opdel tal i lige store dele for at oprette sitemap fra mysql

  2. Afstand i meter mellem to Spacial Points i MySQL-forespørgsel

  3. Eksport af data i SQL Server som INSERT INTO

  4. Sådan kopieres data fra en database/tabel til en anden database/tabel