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

Dois-je concevoir une table avec une clé primaire de varchar ou int ?

Lorsque vous choisissez la clé primaire, vous choisissez généralement également la clé en cluster. Les deux sont souvent confondus, mais vous devez comprendre la différence.

Clés primaires sont des affaires logiques éléments. La clé primaire est utilisée par votre application pour identifier une entité, et la discussion sur les clés primaires porte en grande partie sur l'utilisation de clés naturelles ou de clés de substitution. Les liens vont beaucoup plus en détail, mais l'idée de base est que les clés naturelles sont dérivées d'une propriété d'entité existante comme ssn ou phone number , tandis que les clés de substitution n'ont aucune signification en ce qui concerne l'entité commerciale, comme id ou rowid et ils sont généralement de type IDENTITY ou une sorte d'uuid. Mon opinion personnelle est que les clés de substitution sont supérieures aux clés naturelles, et le choix devrait toujours être des valeurs d'identité pour les applications locales uniquement, des guides pour tout type de données distribuées. Une clé primaire ne change jamais pendant la durée de vie de l'entité.

Clés en cluster sont la clé qui définit le stockage physique des lignes dans la table. La plupart du temps, ils chevauchent la clé primaire (l'identifiant d'entité logique), mais cela n'est pas réellement appliqué ni requis. Lorsque les deux sont différents, cela signifie qu'il existe un index unique non clusterisé sur la table qui implémente la clé primaire. Les valeurs de clé groupées peuvent en fait changer pendant la durée de vie de la ligne, ce qui entraîne le déplacement physique de la ligne dans la table vers un nouvel emplacement. Si vous devez séparer la clé primaire de la clé en cluster (et parfois vous le faites), choisir une bonne clé en cluster est beaucoup plus difficile que de choisir une clé primaire. Deux facteurs principaux déterminent la conception de votre clé en cluster :

  1. Le modèle d'accès aux données le plus courant .
  2. Les considérations relatives au stockage .

Modèle d'accès aux données . Par cela, je comprends la façon dont la table est interrogée et mise à jour. N'oubliez pas que les clés groupées déterminent l'ordre réel des lignes dans la table. Pour certains modèles d'accès, certaines mises en page font toute la différence dans le monde en termes de vitesse de requête ou de mise à jour de la simultanéité :

  • données actuelles par rapport aux données d'archives. Dans de nombreuses applications, les données appartenant au mois en cours sont fréquemment consultées, tandis que celles du mois passé sont rarement consultées. Dans de tels cas, la conception de la table utilise le partitionnement de la table par date de transaction, souvent à l'aide d'un algorithme de fenêtre glissante. La partition du mois en cours est conservée sur le groupe de fichiers situé sur un disque rapide chaud, les anciennes données archivées sont déplacées vers des groupes de fichiers hébergés sur un stockage moins cher mais plus lent. Évidemment, dans ce cas, la clé groupée (date) n'est pas la clé primaire (identifiant de transaction). La séparation des deux est motivée par les exigences d'échelle, car l'optimiseur de requêtes sera en mesure de détecter que les requêtes ne s'intéressent qu'à la partition actuelle et ne regardent même pas les historiques.

  • Traitement de style file d'attente FIFO. Dans ce cas, la table a deux points chauds :la fin où se produisent les insertions (mise en file d'attente) et la tête où se produisent les suppressions (dequeue). La clé en cluster doit en tenir compte et organiser la table de manière à séparer physiquement l'emplacement de la queue et de la tête sur le disque, afin de permettre la concurrence entre la mise en file d'attente et la sortie de la file d'attente, par exemple. à l'aide d'une clé de commande de mise en file d'attente. En pur files d'attente cette clé groupée est la seule clé, puisqu'il n'y a pas de clé primaire sur la table (elle contient des messages , pas des entités ). Mais la plupart du temps, la file d'attente n'est pas pure, elle sert également de stockage pour les entités et de ligne entre la file d'attente et le tableau est estompé. Dans ce cas, il existe également une clé primaire, qui ne peut pas être la clé groupée :les entités peuvent être remises en file d'attente, modifiant ainsi la valeur de la clé groupée de l'ordre de mise en file d'attente, mais elles ne peuvent pas modifier la valeur de la clé primaire. Le fait de ne pas voir la séparation est la principale raison pour laquelle les files d'attente sauvegardées par la table utilisateur sont si notoirement difficiles à obtenir correctement et criblées de blocages :parce que la mise en file d'attente et le retrait de la file d'attente se produisent entrelacés dans la table, au lieu d'être localisés à la queue et à la tête de la file d'attente.

  • Traitement corrélé. Lorsque l'application est bien conçue, elle partitionne le traitement des éléments corrélés entre ses threads de travail. Par exemple, un processeur est conçu pour avoir 8 threads de travail (par exemple, pour correspondre aux 8 processeurs du serveur) afin que les processeurs partitionnent les données entre eux, par exemple. le travailleur 1 ne récupère que les comptes nommés A à E, le travailleur 2 F à J, etc. Dans de tels cas, la table doit être regroupée par le nom du compte (ou par une clé composite dont la position la plus à gauche est la première lettre du nom du compte), afin que les travailleurs localisent leurs requêtes et mises à jour dans la table. Une telle table aurait 8 points chauds distincts, autour de la zone où chaque travailleur se concentre en ce moment, mais l'important est qu'ils ne se chevauchent pas (pas de blocage). Ce type de conception est répandu sur les conceptions OLTP à haut débit et dans les charges de référence TPCC, où ce type de partitionnement se reflète également dans l'emplacement mémoire des pages chargées dans le pool de mémoire tampon (localité NUMA), mais je m'éloigne du sujet.

Considérations relatives au stockage . La largeur de la clé groupée a d'énormes répercussions dans le stockage de la table. D'une part, la clé occupe de l'espace dans chaque page non feuille du b-tree, donc une grande clé occupera plus d'espace. Deuxièmement, et souvent plus important, la clé en cluster est utilisée comme clé de recherche par chaque clé non en cluster, donc chaque la clé non clusterisée devra stocker toute la largeur de la clé clusterisée pour chaque ligne. C'est ce qui rend les grandes clés clusterisées comme varchar(256) et guids de mauvais choix pour les clés d'index clusterisées.
De plus, le choix de la clé a un impact sur la fragmentation de l'index clusterisé, affectant parfois considérablement les performances.

Ces deux forces peuvent parfois être antagonistes, le modèle d'accès aux données nécessitant une certaine grande clé clusterisée qui posera des problèmes de stockage. Dans de tels cas, bien sûr, un équilibre est nécessaire, mais il n'y a pas de formule magique. Vous mesurez et vous testez pour arriver au point idéal.

Alors qu'est-ce qu'on fait de tout ça ? Commencez toujours par considérer la clé en cluster qui est également la clé primaire de la forme entity_id IDENTITY(1,1) NOT NULL . Séparez les deux et organisez le tableau en conséquence (par exemple, partitionnez par date) le cas échéant.