2008-10-03 7 views
17

Estoy diseñando una pequeña base de datos SQL para ser utilizada por una aplicación web.¿Debería tener un campo de clave principal dedicado?

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 utilizará 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 rellenarse automáticamente en la base de datos. ¿Tiene algún sentido tener este campo o sería una pérdida de tiempo?

+0

una excepción comúnmente encontrada es para datos de "sistema". es decir, cosas que está definiendo usted mismo campos de estado, etc. – ShoeLace

Respuesta

25

Yo usaría un PK generado yo solo, por las razones que usted mencionó. 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.

+2

Esta es generalmente la forma aceptada de manejar claves primarias. Nunca debe elegir una columna para su clave principal donde se puede cambiar su valor, ya que luego ingresa en una actualización en cascada para todas las tablas con eso como una clave de Fireign. –

0

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.

2

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

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 esquemas db.

2

Tener una clave primaria entera siempre es algo bueno desde el rendimiento esperado. 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á futuras modificaciones 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 de la columna Nombre teniendo también un índice.

2

Utilizaría un campo de ID generado automáticamente para la clave principal. Es más fácil unirse a las tablas basadas en ID enteros que el texto. Además, si el campo Nombre 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 campo Nombre es siempre ú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 para 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.

1

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 puede construirse a partir de los componentes de los datos que identifican la entidad platónica idealizada a la que se refiere (es decir, nombre + cumpleaños + lugar de nacimiento + nombres de los padres), pero en el mundo real desordenado "claves sintéticas" que pueden identificar su realidad las entidades mundiales dentro del contexto de su base de datos son una forma mucho más práctica de hacer las cosas. (Y los campos anulables pueden ser muy útiles. ¡Tome eso, personas de teoría de diseño relacional!)

+0

Ojalá que Celko nunca se convierta en apilador o que todos tengamos una gran reprimenda. –

+0

¡Oh, todos lo vamos a tener mal cuando eso suceda! –

1

La clave primaria 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 es en una tabla de códigos, por ejemplo, una tabla que asigna 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 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.

+0

Otro ejemplo: 'country_code' (' US', 'UK', etc.). La gente tiende a usar un 'INT' de 4 bytes, cuando un' ASCII 'de CHAR (CHARTER SET)' CHAR (2) toma solo 2 bytes y funciona mejor por otras razones. Cuando Checoslovaquia se dividió en la República Checa y Eslovaquia, tendrías que escribir el código para el diseño de la clave principal. –

6

Aunque es más rápido buscar y unirse a una columna entera (como muchos han señalado), es incluso más rápido no unirse nunca. Al almacenar un natural key, a menudo puede eliminar la necesidad de una unión.

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

Dicho esto, probablemente debería utilizar un entero o GUID como surrogate key 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.

1

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 voy a agregar esto con la esperanza de disipar los mitos del 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 pasar 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 posibilidad de realizar operaciones basadas en conjuntos cuando tiene identificadores de autoevaluo 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 identificadores 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.

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

+0

Tenga en cuenta que la penalización de rendimiento para insertar en tablas padre e hijo solo es necesaria si insiste en crear padre, luego hijos, luego padre, y hijos. Solo crea padres 1K primero y luego los hijos 5K. –

0

Además de lo que se dice, considere usando 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.

Cuestiones relacionadas