¿Debo tener un campo de clave principal dedicado?

Estoy diseñando una pequeña base de datos SQL para ser utilizada por una aplicación web.

Digamos que una tabla en particular tiene un campo Nombre para el que no se permitirá que dos filas tengan el mismo valor. Sin embargo, los usuarios podrán cambiar el campo Nombre en cualquier momento.

La clave principal de esta tabla se usará como clave externa en otras tablas. Por lo tanto, si el campo Nombre se usó como clave principal, cualquier cambio tendría que propagarse a esas otras tablas. Por otro lado, el requisito de exclusividad se manejaría automáticamente.

Mi instinto sería agregar un campo entero para actuar como la clave principal, que podría ser poblada automáticamente por la base de datos. ¿Tiene algún sentido tener este campo o sería una pérdida de tiempo?

Yo usaría un PK generado solo, solo por las razones que mencionaste. Además, indexar y comparar por enteros es más rápido que comparar por cadenas. También puede poner un índice único en el campo de nombre sin convertirlo en una clave principal.

Lo que estás describiendo se llama clave sustituta . Vea el artículo de Wikipedia para la respuesta larga.

Aunque es más rápido buscar y unirse en una columna entera (como muchos han señalado), es aún más rápido no unirse nunca en primer lugar. Al almacenar una clave natural , a menudo puede eliminar la necesidad de unirse.

Para una base de datos pequeña, las actualizaciones de CASCADE a las referencias de claves extranjeras no tendrían mucho impacto en el rendimiento, a menos que estuvieran cambiando muy a menudo.

Dicho esto, probablemente debería usar un entero o GUID como clave sustituta en este caso. Una clave principal actualizable por diseño no es la mejor idea, y a menos que su aplicación tenga una razón comercial muy atractiva para ser única por su nombre, inevitablemente tendrá conflictos.

Sí, y como regla general, siempre, para cada mesa.

Definitivamente no debe utilizar un campo modificable como clave principal y, en la gran mayoría de las circunstancias, no desea utilizar un campo que tenga otro propósito como clave principal.

Esta es una buena práctica básica para los esquemas db.

Tener una clave primaria entera siempre es algo bueno desde el punto de vista del rendimiento. Todas sus relaciones serán mucho más eficientes con una clave primaria entera. Por ejemplo, JOINs será mucho más rápido ( SQL Server ).

También le permitirá modificaciones futuras de la base de datos. Muy a menudo tiene una columna de nombre único solo para descubrir más tarde que el nombre no es exclusivo en absoluto.

En este momento, podría aplicar la singularidad del nombre de la columna al tener también un índice.

Usaría un campo ID autogenerado para la clave primaria. Es más fácil unirse a las tablas basadas en ID enteros que el texto. Además, si el Nombre del campo se actualiza a menudo, si fuera una clave principal, la base de datos se vería en apuros por actualizar el índice en ese campo con mucha más frecuencia.

Si el Nombre del campo siempre es único, debe marcarlo como único en la base de datos. Sin embargo, a menudo habrá una posibilidad (tal vez actualmente pero posiblemente en el futuro en su caso) de dos nombres, por lo que no lo recomiendo.

Otra ventaja de usar identificadores es en el caso de que tenga una necesidad de informes en su base de datos. Si tiene un informe que desea para un conjunto determinado de nombres, el filtro de ID en el informe se mantendrá constante incluso cuando los nombres puedan cambiar.

Si vive en los círculos enrarecidos de los matemáticos teóricos (como C. Date lo hace en the-land-where-there-are-no-nulls, porque todos los valores de datos son conocidos y correctos), entonces las claves primarias se pueden construir desde los componentes de los datos que identifican la entidad platónica idealizada a la que se refiere (nombre + cumpleaños + lugar de nacimiento + nombres de los padres), pero en el mundo real desordenado “claves sintéticas” que pueden identificar a sus entidades del mundo real dentro del El contexto de su base de datos es una forma mucho más práctica de hacer las cosas. (Y los campos anulables pueden ser muy útiles. Tomen eso, ¡gente de teoría de diseño relacional!)

Si su columna de nombre cambiará, no es realmente un buen candidato para una clave principal. Una clave principal debe definir una única fila de una tabla. Si se puede cambiar, realmente no lo está haciendo. Sin saber más detalles acerca de su sistema no puedo decirlo, pero este podría ser un buen momento para una clave sustituta.

También agregaré esto con la esperanza de disipar los mitos sobre el uso de números enteros de incremento automático para todas sus claves principales. NO es siempre una ganancia de rendimiento el usarlos. De hecho, con bastante frecuencia es exactamente lo contrario. Si tiene una columna de incremento automático, significa que cada INSERT en el sistema ahora tiene la sobrecarga adicional de generar un nuevo valor.

Además, como Mark señala, con ID sustitutos en todas sus tablas, si tiene una cadena de tablas relacionadas, para llegar de una a otra es posible que tenga que unir todas esas tablas para recorrerlas. Con claves primarias naturales que generalmente no es el caso. Unir 6 tablas con números enteros suele ser más lento que unir 2 tablas con una cadena.

También suele perder la capacidad de realizar operaciones basadas en conjuntos cuando tiene identificadores de auto incremento en todas sus tablas. En lugar de insertar 1000 filas en una tabla principal, luego insertar 5000 filas en una tabla secundaria, ahora tiene que insertar las filas principales de a una por vez en un cursor u otro bucle solo para obtener las ID generadas para que pueda asignarlas a los niños relacionados. He visto un proceso de 30 segundos convertido en un proceso de 20 minutos porque alguien insistió en usar ID de auto incremento en todas las tablas de una base de datos.

Finalmente (al menos por razones que menciono aquí, sin duda hay otras), el uso de ID de auto incremento en todas sus tablas promueve un diseño deficiente. Cuando el diseñador ya no tiene que pensar en qué puede ser una clave natural para una tabla, generalmente resulta en duplicados erróneos que terminan en los datos. Puede intentar evitar el problema con índices únicos, pero en mi experiencia los desarrolladores y diseñadores no pasan por ese esfuerzo extra y después de un año de usar su nuevo sistema descubren que los datos son un desastre porque la base de datos no tenía restricciones apropiadas en los datos a través de claves naturales.

Ciertamente hay un tiempo para usar claves sustitutas, pero usarlas a ciegas en todas las tablas es casi siempre un error.

La clave principal para un registro debe ser única y permanente . Si un registro tiene una clave simple que cumple ambos, entonces úselo. Sin embargo, no aparecen con mucha frecuencia. Para un registro de persona, el nombre de la persona no es único ni permanente, por lo que debe usar un autoincremento.

El único lugar donde funcionan las claves naturales está en una tabla de códigos, por ejemplo, una tabla que mapea un valor de estado a su descripción. Tiene poco sentido dar a “Activo” una clave principal de 1, “Retardar” una clave principal de 2, etc. Cuando es tan fácil darle a “Activo” una clave principal de “ACT”; “Retrasado”, “DLY”; “En espera”, “HLD”, etc.

Tenga en cuenta también que algunos dicen que debería usar enteros sobre cadenas porque se comparan más rápido. No es verdad La comparación de dos campos de caracteres de 4 bytes llevará exactamente el mismo tiempo que la comparación de dos campos enteros de 4 bytes. Una cuerda más larga llevará, por supuesto, más tiempo, pero si mantienes los códigos cortos, no hay diferencia.

La clave principal debe ser única para cada fila. El entero auto_increment es una muy buena idea, y si no tienes otras ideas sobre llenar la clave primaria, esta es la mejor manera.

Además de todo lo dicho, considere usar un UUID como PK. Le permitirá crear claves que son uniq que abarcan múltiples bases de datos.

Si alguna vez necesita exportar / combinar datos con otra base de datos, entonces los datos siempre serán únicos y las relaciones se pueden mantener fácilmente.