Les GUID peuvent sembler être un choix naturel pour votre clé primaire - et si vous le devez vraiment, vous pourriez probablement argumenter pour l'utiliser pour la CLÉ PRIMAIRE de la table. Ce que je recommande fortement de ne pas faire, c'est d'utiliser la colonne GUID comme clé de clustering , ce que SQL Server fait par défaut, sauf si vous le lui dites expressément.
Vous devez vraiment séparer deux problèmes:
la clé primaire est une construction logique - l'une des clés candidates qui identifie de manière unique et fiable chaque ligne de votre table. Cela peut être n'importe quoi, vraiment - une INT
, une GUID
, une chaîne - choisissez ce qui a le plus de sens pour votre scénario.
la clé de clustering (la ou les colonnes qui définissent l '"index clusterisé" sur la table) - c'est une chose liée au stockage physique , et ici, un petit type de données stable et en constante augmentation est votre meilleur choix - INT
ou BIGINT
comme votre option par défaut.
Par défaut, la clé primaire d'une table SQL Server est également utilisée comme clé de cluster - mais cela n'a pas besoin d'être ainsi! J'ai personnellement constaté des gains de performances massifs lors de la division de la clé primaire / cluster basée sur GUID précédente en deux clés distinctes - la clé primaire (logique) sur le GUID et la clé de clustering (commande) sur une INT IDENTITY(1,1)
colonne distincte .
Comme Kimberly Tripp - la reine de l'indexation - et d'autres l'ont dit à maintes reprises - GUID
car la clé de clustering n'est pas optimale, car en raison de son caractère aléatoire, elle entraînera une fragmentation massive des pages et des index et des performances généralement mauvaises.
Oui, je sais - il y a newsequentialid()
dans SQL Server 2005 et plus - mais même cela n'est pas vraiment et entièrement séquentiel et souffre donc également des mêmes problèmes que le GUID
- un peu moins bien en évidence.
Ensuite, il y a un autre problème à considérer: la clé de clustering d'une table sera ajoutée à chaque entrée de chaque index non clusterisé de votre table également - vous devez donc vraiment vous assurer qu'elle est aussi petite que possible. En règle générale, un INT
avec plus de 2 milliards de lignes devrait être suffisant pour la grande majorité des tables - et par rapport à un GUID
comme clé de clustering, vous pouvez vous épargner des centaines de mégaoctets de stockage sur disque et dans la mémoire du serveur.
Calcul rapide - en utilisant INT
vs GUID
comme clé principale et de clustering:
- Table de base avec 1'000'000 lignes (3,8 Mo contre 15,26 Mo)
- 6 index non clusterisés (22,89 Mo contre 91,55 Mo)
TOTAL: 25 Mo contre 106 Mo - et ce n'est que sur une seule table!
Un peu plus de matière à réflexion - d'excellentes choses par Kimberly Tripp - lisez-le, relisez-le, digérez-le! C'est vraiment l'évangile d'indexation de SQL Server.
PS: bien sûr, si vous ne traitez qu'avec quelques centaines ou quelques milliers de lignes - la plupart de ces arguments n'auront pas vraiment d'impact sur vous. Cependant: si vous entrez dans les dizaines ou les centaines de milliers de lignes, ou si vous commencez à compter des millions - alors ces points deviennent très cruciaux et très importants à comprendre.
Mise à jour: si vous voulez avoir votre PKGUID
colonne comme clé primaire (mais pas votre clé de cluster), et une autre colonne MYINT
( INT IDENTITY
) comme clé de cluster - utilisez ceci:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
Fondamentalement: il vous suffit de dire explicitement à la PRIMARY KEY
contrainte qu'elle est NONCLUSTERED
(sinon elle est créée en tant qu'index cluster, par défaut) - puis vous créez un deuxième index défini commeCLUSTERED
Cela fonctionnera - et c'est une option valable si vous avez un système existant qui doit être "repensé" pour des performances. Pour un nouveau système, si vous partez de zéro et que vous n'êtes pas dans un scénario de réplication, je choisirais toujours ID INT IDENTITY(1,1)
ma clé primaire en cluster - beaucoup plus efficace qu'autre chose!