Sí, absolutamente hay consecuencias negativas por usar una cadena en lugar de un tipo numérico para una Clave primaria, y aún más si esa PK está agrupada (que en realidad es en su caso). Sin embargo, el grado en el que ve el (los) efecto (s) del uso de un campo de cadena es una función de a) cuántas filas hay en esta tabla, yb) cuántas filas en otras tablas tienen Clave externa para esta PK. Si solo tiene 10k filas en esta tabla y 100k filas en algunas otras tablas que FK a esta tabla a través de ese campo, entonces tal vez no sea tan notable. Pero esos efectos ciertamente se vuelven más notorios a medida que aumenta el recuento de filas.
Debe tener en cuenta que los campos en un índice agrupado se transfieren a índices no agrupados. Entonces, no solo está mirando hasta 40 bytes por fila, sino (40 * algún_número) bytes. Y en cualquier tabla FK que tenga esos mismos 40 bytes en la fila, más a menudo habrá un índice no agrupado en ese campo, ya que se está utilizando en JOIN, por lo que ahora se duplica en cualquier tabla que FK éste. Si uno se inclina a pensar que 40 bytes * 1 millón de filas * 10 copias no son motivo de preocupación, consulte mi artículo ¡El disco es barato! ORLY? que detalla todas (o al menos la mayoría) de las áreas afectadas por esta decisión.
La otra cosa a tener en cuenta es que filtrar y ordenar cadenas, especialmente cuando no se utiliza una intercalación binaria (supongo que está utilizando la base de datos predeterminada que generalmente no distingue entre mayúsculas y minúsculas) es mucho menos eficiente (es decir, lleva más tiempo) que cuando se usa INT
/ BIGINT
. Esto afecta a todas las consultas que filtran / unen / clasifican en este campo.
Por lo tanto, usar algo así CHAR(5)
probablemente estaría bien para una PK agrupada, pero principalmente si también se definió con COLLATE Latin1_General_100_BIN2
(o algo así).
¿Y puede [CODE]
cambiar el valor de alguna vez? En caso afirmativo, esa es una razón aún más para no usarlo como PK (incluso si configura los FK en ON UPDATE CASCADE
). Si no puede o no cambiará, eso está bien, pero todavía hay razones más que suficientes para no usarlo como una PK en clúster.
Por supuesto, la pregunta podría estar formulada incorrectamente, ya que parece que actualmente ya tiene este campo en su PK.
De todos modos, su mejor opción, con mucho, es usarlo [ID_CODE]
como PK en clúster, usar ese campo en tablas relacionadas como FK y mantenerlo [CODE]
como un UNIQUE INDEX
(lo que significa que es una "clave alternativa").
Actualización
Un poco más de información basada en esta pregunta en un comentario sobre esta respuesta:
¿Es [ID_CODE], como PRIMARY KEY, la mejor opción si uso la columna [CODE] para buscar la tabla?
Todo esto depende de muchos factores, algunos de los cuales ya he mencionado pero que reafirmaré:
Una clave primaria es cómo se identifica la fila individual, independientemente de si se hace referencia a ella por cualquier clave externa. La forma en que su sistema identifica internamente la fila está relacionada, pero no necesariamente con la forma en que sus usuarios se identifican / esa fila. Cualquier columna NOT NULL con datos únicos podría funcionar, pero hay cuestiones prácticas a considerar, especialmente si la PK es, de hecho, referenciada por alguna FK. Por ejemplo, los GUID son únicos y algunas personas realmente les gusta usarlos por varias razones, pero son bastante malos para los índices agrupados ( NEWSEQUENTIALID
es mejor, pero no perfecto). Por otro lado, los GUID están bien como teclas alternativas y la aplicación los usa para buscar la fila, pero las UNIONES todavía se hacen usando una PK INT (o similar).
Hasta ahora no nos ha dicho cómo se [CODE]
ajusta el campo en el sistema desde todos los ángulos, aparte de ahora mencionar que así es como se buscan las filas, pero ¿es eso para todas las consultas o solo algunas? Por lo tanto:
Esta decisión no puede tomarse únicamente con la pregunta "¿NVARCHAR sí o no?". Una vez más, diré que, en términos generales, no me parece una buena idea, pero ciertamente hay momentos en que está bien. Dado que hay tan pocos campos en esta tabla, no es probable que haya más, o al menos no muchos, índices. Por lo tanto, puede estar bien de cualquier manera para tener [CODE]
como Índice agrupado. Y si ninguna otra tabla hace referencia a esta tabla, entonces también podría estar bien convirtiéndola en PK. Pero, si otras tablas hacen referencia a esta tabla, optaría por el [ID_CODE]
campo como PK, incluso si no está agrupado.