El diseño de mi base de datos actual hace uso de una clave principal de múltiples columnas para usar datos existentes (que de todos modos serían únicos) en lugar de crear una columna adicional que asigne a cada entrada una clave arbitraria. Sé que esto está permitido, pero me preguntaba si esta es una práctica que podría querer usar con precaución y posiblemente evitar (al igual que goto en C).
Entonces, ¿cuáles son algunas de las desventajas que podría ver en este enfoque o las razones por las que podría querer una sola clave de columna?
database-design
Covar
fuente
fuente
Respuestas:
Por lo general, cuando tiene una tabla con una clave primaria de varias columnas, es el resultado de una tabla de unión (muchos a muchos) que se ha elevado para ser su propia entidad (y, por lo tanto, merece su propia clave principal). Hay muchos que argumentan que cualquier tabla de unión DEBE ser una entidad por defecto, pero eso es una discusión para otro día.
Veamos una relación hipotética de muchos a muchos:
Estudiante * --- * Clase
(un estudiante puede estar en varias clases, una clase puede tener varios estudiantes).
Entre esas dos tablas habrá una tabla de unión llamada StudentClass (o ClassStudent dependiendo de cómo la escriba). A veces, desea realizar un seguimiento de cosas como cuando el estudiante estaba en la clase. Entonces lo agregará a la tabla StudentClass. En este punto, StudentClass se ha convertido en una entidad única ... y se le debe dar un nombre para reconocerlo como tal, por ejemplo, inscripción.
Estudiante 1 --- * Matrícula * --- 1 Clase
(un estudiante puede tener muchas Inscripciones, cada Inscripción es para una clase (o en sentido contrario, una Clase puede tener muchas Inscripciones, cada Inscripción es para un Estudiante).
Ahora puede consultar cosas como, ¿cuántos estudiantes se inscribieron en la clase de Química 101 el año pasado? ¿O en qué clases se inscribió el estudiante John Doe mientras asistía a la Universidad de Acme? Esto fue posible sin la clave primaria separada, pero una vez que tenga una clave primaria para la inscripción, una consulta más fácil sería de estas inscripciones (por id), ¿cuántos estudiantes recibieron una calificación aprobatoria?
La determinación de si una entidad merece un PK se reduce a la cantidad de consultas (o manipulación) que hará para esa entidad. Digamos, por ejemplo, que desea adjuntar las tareas completadas para un estudiante en una clase. El lugar lógico para adjuntar esta entidad (Asignación) sería en la entidad de Inscripción. Darle a la inscripción su propia clave principal facilitaría las consultas de Asignación.
fuente
Tiene sentido tener una columna de identificación separada. Cuando desea obtener algo de su tabla de base de datos, es más fácil hacer:
que SELECCIONE lo que sea de la tabla DONDE col1 = 'val1' Y col2 = 'val2' Y col3 = 'val3'
Por ejemplo, en una aplicación web se traduce en una URL que se ve así:
o así:
fuente
SELECT
consultas adicionales . Y, B) , no tengo idea de cómo esto realmente causa algún tipo de requisito de URL (a menos que esté trabajando con un mal marco). Mis URL no tienen ninguna cadena de consulta?id=13
, y mucho menos?col1=val1&col2=val2&col3=val3
.Básicamente, se pregunta si debe usar teclas sustitutas o naturales (en su caso, suena como teclas naturales compuestas ). Aquí hay un gran artículo: http://www.agiledata.org/essays/keys.html
Prefiero las claves sustitutas porque simplifican la administración durante la vida útil de la base de datos (nunca debe preocuparse por la implicación de que las claves cambien el significado, lo que nunca debería suceder, pero ocurre en cualquier sistema real donde los humanos estén involucrados). Sin embargo , si hay muchas tablas de "búsqueda" en la base de datos (es decir, tablas que son básicamente pares clave: valor), las claves sustitutas pueden volverse engorrosas porque tiene que unir esas tablas en la consulta para obtener resultados significativos.
Por ejemplo, supongamos que tiene dos entidades: Dirección y País.
select * from Address where CountryCode = 'US'
select Address.* from Address join Country on Address.CountryID = Country.ID where Country.Code = 'US'
Me siento cómodo exigiendo claves naturales para tablas de búsqueda y claves sustitutas para todo lo demás, si estoy bastante seguro de que las claves naturales no cambiarán con demasiada frecuencia, si es que alguna vez lo hacen.
fuente
Depende de cómo acceda a los datos. Si realiza muchas búsquedas de clave parcial (donde selecciona registros basados en digamos solo dos de las tres claves), entonces querrá conservar las claves de varias partes. OTOH, si tiene muchas relaciones 1: 1 con otras tablas, probablemente tenga más sentido tener una clave sustituta.
fuente
Siempre me gusta tener una clave primaria sustituta para cada tabla. Pero no hay muchas razones "difíciles" para hacer cumplir esto que he escuchado.
La única vez que tuve una mordedura de clave natural de varias columnas fue con ORM. Ocasionalmente tendría problemas con una clave principal de múltiples columnas usando Linq To Entities.
fuente
Nunca digas nunca, pero unirte en 4 columnas es una molestia. Cuantas más columnas tenga con datos inteligentes, mayores serán las posibilidades de que esos valores cambien. Las bases de datos se pueden configurar para mantener la integridad referencial con actualizaciones en cascada.
Siempre puede crear otro índice para manejar los valores únicos.
El rendimiento es probablemente insignificante en la mayoría de los casos, pero puede probar sus consultas con y sin la clave sustituta.
fuente
Me resulta difícil encontrar una buena razón para ordenar una clave por separado, pero como dijiste, mucha gente la introdujo.
No encuentro esto de ayuda (especialmente con el almacenamiento) cuando trato con tablas de hechos / detalles. Ejemplo canónico: una tabla de hechos de ventas con una (clave_cliente, clave_tienda, clave_producto) con cantidad no tiene mucho sentido tener una clave de nivel de registro.
fuente
Tener PK como autoincremento int reduce la molestia si encuentra que su clave compuesta puede tener duplicados.
fuente
Hay una buena discusión desde 2002 sobre Ask Tom . Es específico de Oracle, pero la discusión más amplia es relevante independientemente de la base de datos que esté utilizando.
fuente