Oui, il y a absolument des conséquences négatives à utiliser une chaîne au lieu d'un type numérique pour une clé primaire, et plus encore si ce PK est en cluster (ce qui est effectivement le cas dans votre cas). Cependant, la mesure dans laquelle vous voyez les effets de l'utilisation d'un champ de chaîne est fonction de a) du nombre de lignes de cette table et b) du nombre de lignes des autres tables qui sont à clé étrangère pour ce PK. Si vous n'avez que 10 000 lignes dans cette table et 100 000 lignes dans quelques autres tables qui FK vers cette table via ce champ, alors ce ne sera peut-être pas si visible. Mais ces effets deviennent certainement plus visibles à mesure que le nombre de lignes augmente.
Vous devez tenir compte du fait que les champs d'un index cluster sont reportés sur les index non cluster. Donc, vous ne regardez pas seulement jusqu'à 40 octets par ligne, mais (40 * un_nombre) octets. Et dans toutes les tables FK, vous avez ces mêmes 40 octets dans la ligne, plus souvent qu'autrement, il y aura un index non clusterisé sur ce champ car il est utilisé dans JOINs, donc maintenant il est vraiment doublé dans toutes les tables que FK à celui-là. Si l'on est enclin à penser que 40 octets * 1 million de lignes * 10 copies ne sont rien à craindre, veuillez consulter mon article Disk Is Cheap! ORLY? qui détaille tous (ou au moins la plupart) des domaines touchés par cette décision.
L'autre chose à considérer est que le filtrage et le tri sur les chaînes, en particulier lorsque vous n'utilisez pas un classement binaire (je suppose que vous utilisez la base de données par défaut qui est généralement insensible à la casse) est beaucoup moins efficace (c'est-à-dire prend plus de temps) que lorsque vous utilisez INT
/ BIGINT
. Cela a un impact sur toutes les requêtes qui filtrent / joignent / trient sur ce champ.
Par conséquent, utiliser quelque chose comme CHAR(5)
serait probablement OK pour un PK en cluster, mais surtout s'il était également défini avec COLLATE Latin1_General_100_BIN2
(ou quelque chose comme ça).
Et la valeur de [CODE]
jamais peut-elle changer? Si oui, c'est encore plus de raison de ne pas l'utiliser comme PK (même si vous définissez les FK sur ON UPDATE CASCADE
). Si cela ne peut pas ou ne changera jamais, c'est bien, mais il y a encore plus de raisons de ne pas l'utiliser comme PK en cluster.
Bien sûr, la question peut être mal formulée car il semble que vous ayez déjà ce champ dans votre PK.
Quoi qu'il en soit, votre meilleure option, de loin, est d'utiliser [ID_CODE]
comme Clustered PK, d'utiliser ce champ dans les tables connexes comme FK et de le conserver [CODE]
comme UNIQUE INDEX
(ce qui signifie qu'il s'agit d'une "clé alternative").
Mise à jour
Un peu plus d'informations basées sur cette question dans un commentaire sur cette réponse:
[ID_CODE], en tant que CLÉ PRIMAIRE, est-il la meilleure option si j'utilise la colonne [CODE] pour rechercher la table?
Tout cela dépend d'un grand nombre de facteurs, dont certains que j'ai déjà mentionnés mais qui seront reformulés:
Une clé primaire est la façon dont la ligne individuelle est identifiée, qu'elle soit référencée ou non par des clés étrangères. La façon dont votre système identifie la ligne en interne est liée, mais pas nécessairement la même que, à la façon dont vos utilisateurs s'identifient / cette ligne. Toute colonne NOT NULL avec des données uniques pourrait fonctionner, mais il y a des problèmes pratiques à prendre en compte, surtout si le PK est, en fait, référencé par des FK. Par exemple, les GUID sont uniques et certaines personnes aiment vraiment les utiliser pour diverses raisons, mais elles sont assez mauvaises pour les index clusterisés ( NEWSEQUENTIALID
c'est mieux, mais pas parfait). D'un autre côté, les GUID sont très bien comme clés alternatives et utilisés par l'application pour rechercher la ligne, mais les JOIN se font toujours à l'aide d'un PK INT (ou similaire).
Jusqu'à présent, vous ne nous avez pas dit comment le [CODE]
champ s'intègre dans le système sous tous les angles, en dehors de mentionner maintenant que c'est ainsi que vous recherchez les lignes, mais est-ce pour toutes les requêtes ou juste pour certaines? Par conséquent:
Cette décision ne peut pas être prise uniquement sur la question "NVARCHAR oui ou non?". Je dirai encore que, d'une manière générale, je ne trouve pas que ce soit une bonne idée, mais il y a certainement des moments où c'est bien. Étant donné le peu de champs dans ce tableau, il est peu probable qu'il y ait plus, ou du moins pas beaucoup, d'index. Donc, vous pourriez être d'accord dans les deux cas [CODE]
comme index clusterisé. Et si aucune autre table ne fait référence à cette table, vous pouvez également en faire le PK. Mais, si d'autres tables font référence à cette table, j'opterais pour le [ID_CODE]
champ comme PK, même s'il n'est pas en cluster.