Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Uniqueidentifier vs IDENTITY vs Material Code --quel est le meilleur choix pour la clé primaire ?

GUID peut 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 déconseille fortement de faire utilise le GUID colonne comme clé de clustering , ce que SQL Server fait par défaut, à moins que vous ne lui disiez spécifiquement de ne pas le faire.

Vous devez vraiment séparer deux problèmes :

  1. 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 - un INT , un GUID , une chaîne - choisissez ce qui convient le mieux à votre scénario.

  2. la clé de clustering (la colonne ou les colonnes qui définissent "l'index clusterisé" sur la table) - c'est un physique chose liée au stockage, et ici, un petit type de données stable et en constante augmentation est votre meilleur choix - INT ou BIGINT comme option par défaut.

Par défaut, la clé primaire d'une table SQL Server est également utilisée comme clé de clustering - mais cela n'a pas besoin d'être ainsi ! J'ai personnellement constaté des gains de performances considérables lors de la séparation de la clé primaire / en cluster précédente basée sur le GUID en deux clés distinctes - la clé primaire (logique) sur le GUID , et la clé de regroupement (ordre) sur un INT IDENTITY(1,1) séparé colonne.

En tant que Kimberly Tripp - la reine de l'indexation - et d'autres l'ont dit à maintes reprises - un 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 médiocres.

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 - juste un peu moins en évidence.

Ensuite, il y a un autre problème à considérer :la clé de clustering d'une table sera également ajoutée à chaque entrée de chaque index non clusterisé de votre table - vous voulez donc vraiment vous assurer qu'elle est aussi petite que possible. Typiquement, un INT avec plus de 2 milliards de lignes devrait être suffisant pour la grande majorité des tables - et par rapport à un GUID en tant que clé de clustering, vous pouvez économiser 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é primaire et clé de cluster :

  • 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 c'est juste sur une seule table !

Un peu plus de matière à réflexion - d'excellents trucs de Kimberly Tripp - lisez-le, relisez-le, digérez-le ! C'est vraiment l'évangile de l'indexation SQL Server.

Sauf si vous avez une très bonne raison , je dirais qu'il faut utiliser un INT IDENTITY pour presque toutes les "vraies" tables de données comme valeur par défaut pour leur clé primaire - c'est unique, c'est stable (ne change jamais), c'est étroit, ça augmente toujours - toutes les bonnes propriétés que vous souhaitez avoir dans une clé de clustering pour des performances rapides et fiables de vos tables SQL Server !

Si vous avez une valeur de clé "naturelle" qui possède également toutes ces propriétés, vous pouvez également l'utiliser à la place d'une clé de substitution. Mais deux chaînes de longueur variable de max. 20 caractères chacun ne répondent pas à ces exigences à mon avis.