2008-09-02 13 views
14

Tengo las siguientes tablas en mi base de datos que tienen una relación muchos-a-muchos relación, que se expresa por una tabla de conexión que tenga las claves externas a las claves primarias de cada uno de los cuadros principales:¿Una o dos claves principales en la tabla de muchos a muchos?

  • Widget: moduloid (PK), Título, Precio
  • usuario: identificación de usuario (PK), Nombre, Apellido

Suponga que cada combinación del usuario-Widget es único. Veo dos opciones para la forma de estructurar la tabla de conexión que define la relación de datos:

  1. UserWidgets1: UserWidgetID (PK), moduloid (FK), identificación de usuario (FK)
  2. UserWidgets2: moduloid (PK, FK), ID de usuario (PK, FK)

La opción 1 tiene una sola columna para la clave principal. Sin embargo, esto parece innecesario ya que la única información que se almacena en la tabla es la relación entre las dos tablas principales, y esta relación en sí misma puede formar una clave única. Por lo tanto, conduce a la opción 2, que tiene una clave principal de dos columnas, pero pierde el identificador único de una columna que tiene la opción 1. También podría agregar opcionalmente un índice exclusivo de dos columnas (WidgetID, UserID) a la primera tabla.

¿Hay alguna diferencia real entre los dos en cuanto a rendimiento, o alguna razón para preferir un enfoque sobre el otro para estructurar la tabla de muchos a muchos de UserWidgets?

+0

Los índices que necesita están dictados por los requisitos de su consulta, no por el diseño del esquema. – dkretz

Respuesta

24

Solo tiene una clave principal en ambos casos. El segundo es lo que se llama una clave compuesta. No hay una buena razón para presentar una nueva columna. En la práctica, deberá mantener un índice único en todas las claves candidatas. Agregar una nueva columna no le compra más que gastos de mantenimiento.

Ir con la opción 2.

+0

Se puede compilar una clave principal; los términos no son exclusivos. – paulmurray

+2

@paulmurray: Creo que la respuesta anterior dice que tiene una clave principal en ambos casos, incluido el caso en el que tiene una clave compuesta. ¿Tuviste algo que agregar a eso? – Apocalisp

0

Como cada combinación de User-Widget es única, debe representarla en su tabla haciendo que la combinación sea única. En otras palabras, vaya con la opción 2. De lo contrario, puede tener dos entradas con el mismo widget y las mismas ID de usuario pero con diferentes ID de widget de usuario.

0

El userwidgetid en la primera tabla no es necesaria, ya que como usted ha dicho la singularidad proviene de la combinación de la moduloid y el identificador de usuario.

Usaría la segunda tabla, conservaría las claves foriegn y añadiría un índice único en widgetid y userid.

Así:

 
userwidgets(widgetid(fk), userid(fk), 
      unique_index(widgetid, userid) 
) 

Se obtiene mejor preformance en no tener la clave principal adicional, ya que la base de datos no tendría que calcular el índice de la clave. En el modelo anterior, aunque este índice (a través del unique_index) todavía se calcula, pero creo que es más fácil de entender.

2

¿Cuál es el beneficio de una clave principal en este escenario? Considere la opción de no tener clave principal: UserWidgets3: WidgetID (FK), ID de usuario (FK)

Si desea exclusividad, utilice la clave compuesta (UserWidgets2) o una restricción de exclusividad.

La ventaja de rendimiento habitual de tener una clave principal es que a menudo consulta la tabla con la clave principal, que es rápida. En el caso de tablas de muchos a muchos, generalmente no consulta por la clave principal, por lo que no hay ningún beneficio de rendimiento. Muchas de las tablas se consultan por sus claves externas, por lo que debería considerar agregar índices en WidgetID y UserID.

2

La opción 2 es la respuesta correcta, a menos que tenga una muy buena razón para agregar una clave numérica sustituta (que ha hecho en la opción 1).

Las columnas de clave numéricas sustitutas no son 'claves primarias'. Las claves primarias son técnicamente una de las combinaciones de columnas que identifican de manera única un registro dentro de una tabla.

Cualquier persona que construya una base de datos debe leer este artículo http://it.toolbox.com/blogs/database-soup/primary-keyvil-part-i-7327 de Josh Berkus para comprender la diferencia entre las columnas de clave numéricas sustitutas y las claves principales.

En mi experiencia, la única razón real para agregar una clave numérica sustituta a su tabla es si su clave principal es una clave compuesta y necesita ser utilizada como referencia de clave externa en otra tabla. Solo entonces deberías incluso pensar en agregar una columna extra a la mesa.

Cada vez que veo una estructura de base de datos donde cada tabla tiene una columna 'id', es probable que haya sido diseñada por alguien que no aprecia el modelo relacional e invariablemente mostrará uno o más de los problemas identificados en Josh's artículo.

3

Acepto las respuestas anteriores, pero tengo una observación que agregar. Si desea agregar más información a la relación y permitir más relaciones entre las mismas dos entidades, necesita la opción uno.

Por ejemplo, si desea hacer un seguimiento de todas las veces que el usuario 1 ha usado el widget 664 en la tabla de userwidget, el ID de usuario y el widgetid ya no son únicos.

5

Personalmente, me gustaría he sintético/sustituta columna de clave en muchos-a-muchos cuadros por las siguientes razones:

  • Si ha utilizado teclas numéricas sintéticos en las tablas a continuación, tienen la entidad lo mismo en las tablas de relaciones mantiene la coherencia en el diseño y la convención de nomenclatura.
  • Puede ser el caso en el futuro que la tabla de muchos a muchos se convierta en una entidad principal en una entidad subordinada que necesita una referencia única a una fila individual.
  • Realmente no va a utilizar ese espacio de disco adicional.

La clave sintética no es un sustituto de la clave natural/compuesto, ni se convierte en el PRIMARY KEY para esa tabla sólo porque es la primera columna de la tabla, por lo que en parte está de acuerdo con el artículo de Josh Berkus. Sin embargo, no estoy de acuerdo en que las claves naturales siempre sean buenas candidatas para PRIMARY KEY's y, desde luego, no deberían utilizarse si se van a utilizar como claves foráneas en otras tablas.

+0

Me doy cuenta de que esto fue respondido hace mucho tiempo, pero ¿no sería la clave compuesta aún una referencia única a una fila individual para una tabla padre (su punto 2)? – crush

+1

@crush: sí, sería único, pero crear una restricción en una clave compuesta es frágil/inconsistente en todas las plataformas. Prefiero ser explícito y consistente. Cada tabla tiene una columna de identidad. – Guy

5

La opción 2 usa una clave de compund simple, la opción 1 usa un surrogate key. La opción 2 es preferible en la mayoría de los escenarios y está cerca del modelo de investigación ya que es una buena clave candidata.

hay situaciones en que es posible que desee utilizar una clave sustituta (Opción 1)

  1. Usted no es que la clave compuesto es una buena clave candidata con el tiempo. Particularmente con datos temporales (datos que cambian con el tiempo). ¿Qué sucede si quiere agregar otra fila a la tabla UserWidget con el mismo UserId y WidgetId? Piense en el empleo (EmployeeId, EmployeeId): funcionaría en la mayoría de los casos, excepto si alguien volviera a trabajar para el mismo empleador en una fecha posterior
  2. Si está creando mensajes/transacciones comerciales o algo similar que requiera una clave más fácil usar para integración Replicación tal vez?
  3. Si desea crear sus propios mecanismos de auditoría (o similares) y no desea que las claves sean demasiado largas.

Como regla general, al modelar datos, encontrará que la mayoría de las entidades asociativas (muchas a muchas) son el resultado de un evento. La persona toma un empleo, el artículo se agrega a la canasta, etc. La mayoría de los eventos tienen una dependencia temporal del evento, donde la fecha o la hora son relevantes, en cuyo caso una clave sustituta puede ser la mejor alternativa.

Por lo tanto, tome la opción 2, pero asegúrese de tener el modelo completo.

1

Me gustaría ir con ambos.

Escúchame:

clave El compuesto es obviamente la manera agradable, correcto para ir en la medida en que refleja el significado de sus datos van. No hay duda.

Sin embargo: He tenido todo tipo de problemas para hacer que hibernar funcione correctamente a menos que use una sola clave primaria generada: una clave sustituta.

Entonces yo usaría un de datos lógicos y físicos modelo. El uno lógico tiene la clave compuesta. El modelo físico, que implementa el modelo lógico, tiene la clave sustituta y las claves externas.

Cuestiones relacionadas