Claves Primarias compuestas : ¿es bueno o malo

He sido el diseño de una base de datos para una tienda en línea del sistema. La pregunta que he llegado a través de la lectura de algunos artículos en este sitio web es que a pesar de que puede utilizar claves primarias compuestas en el caso de que me va a explicar a continuación, es realmente una mala práctica (de acuerdo a los puestos que he leído en este respeto stackoveflow, muchos dice que es una mala práctica, así que por eso estoy preguntando).

Quiero para almacenar los pagos de los pedidos en una tabla separada. La razón es que, una orden puede tener muchos elementos que se manejan en una tabla separada en el formulario de relación de muchos a muchos. Ahora, si yo no uso las claves primarias compuestas para mi tabla de pago, voy a perder mi única PaymentID:

[PaymentId] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
[OrderId] INT NOT NULL PRIMARY KEY --Also a Foreign Key--

Ahora, si me acaba de quitar la Clave Principal para el OrderId, voy a perder mi uno a uno relación aquí, así que Many OrderIds can be associated to many PaymentIds, y yo no quiero esto.

Esta es la razón por la previamente a preguntas frecuentes aquí han concluido (en su mayoría) que la clave compuesta es una mala idea. Así que quiero aclarar esto para mí; si es malo, ¿cuál es la mejor práctica, entonces?

  • Si he entendido correctamente, en este caso, usted puede simplemente añadir un aparte de la restricción unique en OrderId, y han PaymentId como la clave principal.
  • No entendí la parte: «La razón es que, una orden puede tener muchos elementos que se manejan también en una tabla separada en el formulario de relación de muchos a muchos.»? si usted tiene order_id en payments tabla, a continuación, todo lo que tienes que hacer es hacer referencia a él con orders tabla, ¿Cómo podría usted perder único PaymentID?
  • Sí, pero 1 de la Orden en ese caso puede tener varios pagos que es malo, yo estoy en lo correcto ?
  • En mi opinión, el haber varios pagos de una orden no está del todo mal.
  • Por favor, mira mi comentario anterior
  • En el mundo real, es malo, porque eso no puede suceder
  • ¿Cuál es la clave principal compuesta de las que están hablando? (PaymentId,OrderId)? Con FKs (PaymentId) y (Idpedido)? Sería útil si usted dio SQL apropiado para su elección. Tu pregunta no es clara.

InformationsquelleAutor JAX | 2014-09-27

4 Kommentare

  1. 45

    No hay ninguna conclusión que las claves primarias compuestas son malos.

    La mejor práctica es tener algunos columna o columnas que identifican de forma única una fila. Pero en algunas de las tablas de una sola columna no es suficiente por sí mismo para identificar una fila.

    SQL (y el modelo relacional) permite una clave principal compuesta. Es una buena práctica en algunos casos. O bien, otra forma de verlo es que no es una mala práctica en todos los casos.

    Algunas personas tienen la opinión de que cada tabla debe tener una columna de tipo entero que genera automáticamente los valores únicos, y que debe servir como clave principal. Algunas personas también afirman que esta columna de clave principal siempre debe ser llamado id. Pero esos son convenios, no necesariamente las mejores prácticas. Los convenios tienen algún beneficio, porque simplifica ciertas decisiones. Pero convenciones también son restrictivas.

    Usted puede tener un pedido con varios pagos debido a que algunas personas de compra en layaway, o bien de fuentes múltiples de pago (dos tarjetas de crédito, por ejemplo), o de dos diferentes que la gente quiere pagar por una parte de la orden (I suelen ir a un restaurante con un amigo, y cada uno de nosotros pagar por nuestra propia comida, por lo que el personal de proceso de la mitad de la orden en cada una de nuestras tarjetas de crédito).

    Me gustaría diseñar el sistema que se describe de la siguiente manera:

    Products  : product_id (PK)
    
    Orders    : order_id (PK)
    
    LineItems : product_id is (FK) to Products
                order_id is (FK) to Orders
                (product_id, order_id) is (PK)
    
    Payments  : order_id (FK)
                payment_id - ordinal for each order_id
                (order_id, payment_id) is (PK)

    Esto también está relacionado con el concepto de relación de identificación. Si es la definición de que un pago sólo existe debido a una orden de existir, luego de realizar el pedido de la parte de la clave primaria.

    Nota la LineItems tabla también carece de su propia auto-incremento de una sola columna de clave principal. Muchos-a-muchos de tabla es un ejemplo clásico de un buen uso de una clave principal compuesta.

    • «no es una mala práctica en todos los casos» . . . Estoy de acuerdo con eso.
    • ¿Qué hace un muchos-a-muchos de relación entre los pedidos y los pagos tienen que ver con esta pregunta?
    • Nada que ver con esta parte de la pregunta, me explicó por qué quiero que las cosas se dividen en diferentes tablas
    • Gracias Bill, su respuesta es muy agradable, en realidad su idea en varios pagos es correcto, estoy de acuerdo con usted
    • Algunos de la opinión en contra de declarar claves primarias compuestas parece ser impulsado por la forma en que algunos ORM herramientas de trabajo. Pierre puede o no puede estar en esta situación.
    • a la derecha, ORM, frameworks como Ruby on Rails, que comenzó con la frase «obstinado de software» acerca de PK diseño se id solo, pero esto es como decir que no funciones de apoyo con más de un argumento. En las versiones después de la primera, RoR admite llaves primarias compuestas. Todos los marcos finalmente llegamos a la misma conclusión. Si alguien sigue el uso de un ORM que no admite compuesto PK es, necesita actualizar.
    • Gracias por la aclaración. Estoy de acuerdo. Mi comentario se centra principalmente en los orígenes de las opiniones en contra de compuestos PKs en algunas de las anteriores respuestas aquí en tanto.
    • También vale la pena señalar que autoincrement garantiza la unicidad de las filas de la tabla, pero no necesariamente la identidad singular de cada una de las materia entidades. Un error de operación puede resultar en la entrada duplicada de la misma persona, por supuesto, producto, etc.
    • a la derecha, sino compuesto PK no garantiza que cualquiera de los dos. Eso no es generalmente un problema en el modelo relacional, ya que está implícito en el modelo que el valor 1234 en una columna no significa la misma cosa que el valor 1234 en una situación totalmente diferente de la columna.
    • A la derecha, es un tema aparte.
    • No sería mejor invertir el orden de la clave primaria en LineItems, por lo que se inserta en el índice están ordenados por id_pedido, product_id, y no al revés? Único sabio es el mismo
    • depende de cómo usted va a la consulta de la tabla. Si desea favor de búsqueda por producto la mayoría de las veces, entonces sería una buena idea para definir la clave primaria de la manera que me muestran. Si desea que la búsqueda por el fin de ser más eficientes, a continuación, cambiar el orden de las columnas como usted sugiere.
    • Me refiero a que para las inserciones, el rendimiento debe ser mejor con el id de pedido en primer lugar, ya no sería necesario cambiar alrededor de filas al azar basado en el número de producto utilizado. Que ya estarían en el orden en que se inserta, de forma natural. La adición de otro índice (no exclusivo) para el product_id debe resolver la consulta, problema, ¿no?
    • estás asumiendo que las plaquitas están comprometidos en perfecto orden secuencial order_id. Si los insertos están llegando a un ritmo lento, esto podría ser cierto. Pero si es tan lento, la inserción en el no-orden secuencial de no ser un cuello de botella. Si la llegan los pedidos tan rápido que usted tiene que optimizar insertar orden, probablemente están llegando en muchos subprocesos simultáneos, y no van a ser perfectamente secuencial.
    • Bien. En una pesada insertar situación en que me encontraba teniendo en cuenta que tras la order_id insertar de forma incremental podría resultar en una gran cantidad más de grupo de búfer de aciertos de caché, aunque no estaban exactamente en orden. Pero entiendo tu punto de vista.
    • De todos modos, tienes razón que la inserción en el orden secuencial puede ser un beneficio. Vea este blog buscando alguna explicación inteligente y gráfica de la prueba: percona.com/blog/2015/04/03/…
    • Yo estaba tratando de hacer exactamente el punto de que el blog hace 🙂
    • algunas convenciones de nomenclatura de aquí son realmente útiles… llamar a una columna de clave ‘order_id_pk’ o ‘order_id_fk’ es súper útil. De esa manera cuando usted está escribiendo consultas o de la lectura del antiguo código, usted sabe que cuando usted está tratando con las claves principales o claves foráneas.

  2. 19

    Esta pregunta está peligrosamente cerca pidiendo opiniones, que pueden generar las guerras de religión. Como alguien que está muy sesgado hacia la auto-aumento de las claves principales de enteros en mis tablas (se llama algo así como TablenameId, no Id), hay una situación en que es opcional.

    Creo que las otras respuestas de la dirección ¿por qué quieres las claves primarias.

    Una razón muy importante es para fines de referencia. En una base de datos relacional, cualquier entidad que podría-en teoría-se hace referencia a otra entidad a través de relaciones de clave externa. Para claves foráneas, que sin duda desea una columna únicamente para definir una fila. De lo contrario, usted tiene que tratar con múltiples columnas de diferentes tablas que se alinean unos con otros. Esto es posible, pero complicado.

    La tabla se hace referencia a que no es una «entidad» de la tabla es un «cruce» de la tabla. Es una base de datos relacional para construir la manipulación de muchos-a-muchos de relaciones. Porque realmente no representan a una entidad, no debe tener relaciones de clave externa. Por lo tanto, una clave principal compuesta es razonable. Hay algunas situaciones, como cuando usted se preocupa por el tamaño de la base, donde dejando fuera artificial clave principal es incluso deseable.

    • Podría usted por favor vuelvan a formular más claramente «Para claves foráneas, que sin duda desea una columna únicamente para definir una fila.»
    • Si usted puede contestar @philipxy del comentario, que sería de gran ayuda. Como actualmente estoy en una fase de diseño en la contemplación de los trade-offs.
    • Creo que quiere decir que si usted desea vincular dos tablas, que las vincula por el identificador único. La clave primaria de la otra tabla se convierte en la clave externa en la tabla. Y él está diciendo que su preferencia es que si la clave primaria no es una clave compuesta, porque él no quiere tener varias columnas importados en su mesa, más bien, quizás solo quiero uno.
  3. 7

    El espacio en disco es barato, por lo que una clave principal agrupado en un int identity(1,1) nombre después de una convención (como pk + nombre de la tabla) es una buena práctica. Se hacen consultas, se une, índices y demás restricciones fácil de manejar.

    Sin embargo hay una buena razón para no hacerlo (en MS SQL Server, al menos): si desea administrar el físico de la clasificación de los datos en el sistema de almacenamiento subyacente.

    La clave principal clúster determina la física de ordenación. Si lo haces en una columna de identidad, el orden de clasificación es básicamente la inserción de la orden. Sin embargo, esta puede no ser la mejor, especialmente si usted siempre se consulta la tabla de la misma manera.
    En tablas muy grandes, obteniendo el derecho de física de ordenación que hace que las consultas mucho más rápido. Por ejemplo, puede que desee que el índice agrupado en un compuesto de dos columnas.

  4. 5

    Las mejores prácticas son útiles en el mejor, pero cegadora en el peor. Ir en contra de una de las mejores prácticas no es un pecado. Sólo asegúrese de saber qué tipo de trade-off que están haciendo.

    Motores de base de datos puede ser muy complicado las cosas. Sin saber de qué optimizaciones son realizados por un determinado motor, será difícil determinar qué tipos de construcciones ofrecerá el mejor rendimiento (porque supongo que la cuestión que estamos hablando aquí es de rendimiento). Claves compuestas pueden ser problemáticos para las tablas de gran tamaño en una especie de base de datos, pero no tiene ningún impacto notable para otro.

    Una práctica útil que he aprendido es que siempre se esfuerzan para tener mis aplicaciones tan simples como sea posible. Hacer uso de claves compuestas ahorrarte el tener que realizar búsquedas antes de inserciones, o alguna otra molestia? El uso de ellos. Si, sin embargo, observe que el uso de ellos hace que la aplicación ya no cumplen algunos requisitos de desempeño, considere la posibilidad de una solución sin ellos.

    • «Existe la probabilidad de un aumento exponencial de la complejidad de cada llave incluida» — por Favor, alguien que lee esto, hazte un favor y estudio de los 101 de bases de datos relacionales. Esta declaración y el siguiente argumento simplemente no tiene sentido. El índice del nivel de estructuras como B(+)de los Árboles que los Rdbms uso están diseñados para manejar claves compuestas igual de bien, y ciertamente no en un aumento exponencial de costos. Y hay muchas otras estructuras de índices…
    • Bueno, esta respuesta está en la parte inferior de la lista por una razón. 😉 Yo simplemente no hacer un muy buen trabajo. Voy a quitar las cosas que no es verdad y tratar de solucionar algunos de los errores gramaticales.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea