Quiero saber si las claves primarias compuestas son una mala práctica y, de no ser así, en qué escenarios es recomendable usar.
Mi pregunta está basada en este artículo.
La parte sobre las claves primarias compuestas:
Mala práctica No. 6: claves primarias compuestas
Este es un punto controvertido, ya que muchos diseñadores de bases de datos hablan hoy en día sobre el uso de un campo autogenerado de ID de entero como la clave principal en lugar de uno compuesto definido por la combinación de dos o más campos. Actualmente se define como la "mejor práctica" y, personalmente, tiendo a estar de acuerdo con ella.
Sin embargo, esto es solo una convención y, por supuesto, los DBE permiten la definición de claves primarias compuestas, que muchos diseñadores piensan que son inevitables. Por lo tanto, al igual que con la redundancia, las claves primarias compuestas son una decisión de diseño.
Sin embargo, tenga cuidado, si se espera que su tabla con una clave primaria compuesta tenga millones de filas, el índice que controla la clave compuesta puede crecer hasta un punto donde el rendimiento de la operación CRUD se degrada mucho. En ese caso, es mucho mejor usar una clave primaria de ID de entero simple cuyo índice sea lo suficientemente compacto y establezca las restricciones DBE necesarias para mantener la unicidad.
fuente
Respuestas:
¡Decir que el uso de
"Composite keys as PRIMARY KEY is bad practice"
es un completo disparate!¡Los compuestos a
PRIMARY KEY
menudo son algo muy "bueno" y la única forma de modelar situaciones naturales que ocurren en la vida cotidiana!¡Piense en el clásico ejemplo de enseñanza Databases-101 de estudiantes y cursos y en los muchos cursos tomados por muchos estudiantes!
Crear mesas curso y alumno:
Le daré el ejemplo en el dialecto PostgreSQL (y MySQL ): debería funcionar para cualquier servidor con un poco de ajuste.
Ahora, es obvio que desee realizar un seguimiento de las cuales estudiante está tomando el cual por supuesto - por lo que tiene lo que se llama
joining table
(también llamadoslinking
,many-to-many
om-to-n
tablas). ¡También se conocen comoassociative entities
en jerga más técnica!1 curso puede tener muchos estudiantes.
1 estudiante puede tomar muchos cursos.
Entonces, creas una tabla de unión
Ahora, la única manera sensata de darle una mesa a esta
PRIMARY KEY
es hacer que seaKEY
una combinación de curso y estudiante. De esa manera, no puedes obtener:un duplicado de combinación de estudiante y curso
un curso solo puede tener al mismo estudiante matriculado una vez, y
un estudiante solo puede matricularse en el mismo curso solo una vez
también tiene una búsqueda preparada
KEY
en el curso por estudiante, también conocido como índice de cobertura ,¡Es trivial encontrar cursos sin estudiantes y estudiantes que no toman cursos!
- El ejemplo db-fiddle tiene la restricción PK plegada en CREATE TABLE - Se puede hacer de cualquier manera. Prefiero tener todo en la declaración CREATE TABLE.
Ahora, si descubriera que las búsquedas de estudiantes por curso fueron lentas, use un
UNIQUE INDEX
on (sc_student_id, sc_course_id).No hay ninguna bala de plata para añadir índices - que van a hacer que
INSERT
s yUPDATE
es más lento, pero en la gran ventaja de la enorme disminución deSELECT
los tiempos! Depende del desarrollador decidir indexar dado su conocimiento y experiencia, pero decir que los compuestos siemprePRIMARY KEY
son malos es simplemente incorrecto.¡En el caso de unir tablas, generalmente son las únicas
PRIMARY KEY
que tienen sentido! ¡Las tablas de unión también son muy frecuentemente la única forma de modelar lo que sucede en los negocios o la naturaleza o en prácticamente todos los ámbitos que se me ocurren!Esta PK también es útil como una
covering index
que puede ayudar a acelerar las búsquedas. En este caso, sería particularmente útil si uno estuviera buscando regularmente en (course_id, student_id), lo cual, uno podría imaginar, ¡a menudo puede ser el caso!Este es solo un pequeño ejemplo de dónde un compuesto
PRIMARY KEY
puede ser una muy buena idea, ¡y la única forma sensata de modelar la realidad! Fuera de mi cabeza, puedo pensar en muchos, muchos más.Un ejemplo de mi propio trabajo!
¡Considere una tabla de vuelo que contiene un flight_id, una lista de aeropuertos de salida y llegada y los horarios relevantes y luego también una tabla de cabina con tripulantes!
La única forma sensata de modelar esto es tener una tabla flight_crew con el flight_id y el crew_id como atributos, ¡y la única forma sensata
PRIMARY KEY
es utilizar la clave compuesta de los dos campos!fuente
id
clave principal y un índice únicocs_student_id
cs_course_id
y tenga los mismos resultados?Mi opinión a medias: una "clave primaria" no tiene que ser la única clave única utilizada para buscar datos en la tabla, aunque las herramientas de administración de datos la ofrecerán como selección predeterminada. Entonces, para elegir si desea tener un compuesto de dos columnas o un número generado aleatoriamente (probablemente en serie) como la clave de la tabla, puede tener dos claves diferentes a la vez.
Si los valores de datos incluyen un término único adecuado que puede representar la fila, prefiero declararlo como "clave primaria", incluso si es compuesto, que usar una clave "sintética". La clave sintética puede funcionar mejor por razones técnicas, pero mi elección predeterminada es designar y usar el término real como clave principal, a menos que realmente necesite ir en sentido contrario para que su servicio funcione.
Un Microsoft SQL Server tiene la característica distinta pero relacionada del "índice agrupado" que controla el almacenamiento físico de datos en orden de índice, y también se usa dentro de otros índices. De forma predeterminada, se crea una clave primaria como un índice agrupado, pero en su lugar puede elegir no agrupado, preferiblemente después de crear el índice agrupado. Por lo tanto, puede tener una columna de identidad entera generada como índice agrupado y, por ejemplo, el nombre de archivo nvarchar (128 caracteres) como clave principal. Esto puede ser mejor porque la clave de índice agrupada es estrecha, incluso si almacena el nombre del archivo como el término de clave externa en otras tablas, aunque este ejemplo es un buen caso para no hacerlo.
Si su diseño involucra la importación de tablas de datos que incluyen una clave primaria inconveniente para identificar datos relacionados, entonces está bastante atrapado con eso.
https://www.techopedia.com/definition/5547/primary-key describe un ejemplo de elegir si almacenar datos con el número de seguro social de un cliente como la clave del cliente en todas las tablas de datos, o generar un id_cliente arbitrario cuando registrarlos En realidad, este es un grave abuso de SSN, aparte de si funciona o no; Es un valor de datos personales y confidenciales.
Por lo tanto, una ventaja de usar un hecho del mundo real como clave es que sin volver a unirse a la tabla "Cliente", puede recuperar información sobre ellos en otras tablas, pero también es un problema de seguridad de datos.
Además, tiene problemas si el SSN u otra clave de datos se registró incorrectamente, por lo que tiene el valor incorrecto en 20 tablas restringidas en lugar de solo en "Cliente". Mientras que el customer_id sintético no tiene un significado externo, no puede ser un valor incorrecto.
fuente