2009-06-22 16 views
14

duplicado: Many to Many Relation Design - Intersection Table Design¿Usar claves compuestas? ¿O siempre usas claves sustitutivas?

Si tengo estas tablas (* = clave principal):

user 
    id* 
    name 

group 
    id* 
    name 

¿Es esto mejor?

user_group 
    user_id* 
    group_id* 

¿O es mejor?

user_group 
    id* 
    user_id 
    group_id 
+0

Mejor es subjetivo. Ambos funcionarán bien. Mi voto personal sería para clave compuesta, pero de nuevo preferencia personal. –

+0

Este es un duplicado de varias otras preguntas sobre SO. Es una pregunta legítima, pero se ha formulado y respondido antes. –

+4

El enlace que se indicó como duplicado tiene una respuesta aceptada que realmente no responde a esta pregunta. –

Respuesta

10

estoy siempre a votar para las llaves que son lo más estrecha posible, estática (no cambia) y por lo tanto por lo general a favor de un INT sustituta como una clave más de una clave compuesta.

Si desea hacer referencia a una clave compuesta de otra tabla, siempre tendrá que especificar varias condiciones, que a veces pueden ser bastante difíciles de manejar.

También puedes ver algunos de los enlaces:

(por supuesto, otros es probable que publicar al menos 10 enlaces PRO claves naturales :-))

No hay daño al usar una llave sustituta - ¡adelante! :-)

Marc

+0

En este ejemplo, UserId y GroupId no son claves naturales. Son claves foráneas que cada una hace referencia a un sustituto. La cuestión de las llaves naturales ni siquiera surge en este caso. –

10

Dado que ambos user_id y group_id ya son claves suplentes y por lo tanto garantiza que sea único (correcta aplicación dada de la aplicación), la adición de un tercer ID es totalmente redundante.

A menos que esté utilizando algún tipo de ORM que (lamentablemente) suele hacer más complejo el manejo de claves compuestas. En ese caso, debe evaluar el costo de la redundancia frente a la facilidad de desarrollo con su ORM elegido.

+0

pero en caso de que se requiera una actualización, por ej. como cambiar la identificación del grupo de un usuario en particular, entonces es difícil actualizar la clave compuesta ... ¿no es así? – Anand

10

Siempre que he omitido una clave primaria sustituta de una tabla de unión, me arrepiento. Parece que cuando escribo el código para administrar la relación es muy útil tener una clave primaria sustituta. Por lo general, sigo un patrón de registro activo y estoy usando ASP.NET MVC, por lo que su kilometraje puede variar. En el mundo de MVC, tener una única clave de identificación que puedes poner al final de la URL es muy ventajoso.

+0

¿Para qué? ¿Y de qué forma agregar una única identificación es mucho mejor que poner dos? –

+2

La razón básica es que en MVC el patrón de url es típicamente,/controller/action/id. Si no utilizo una clave sustituta, mi URL termina como/controller/action /? User_id = ... & group_id = ..., lo que también significa que necesito incluir ambos identificadores en la vista como entradas ocultas, etc. Una única identificación simplemente encaja en el patrón de forma más clara. – tvanfosson

+1

¿Por qué habría una URL para un enlace "objeto"? Solo habría URL para agrupar entidades o entidades miembros. Un enlace no debe ser un objeto en su espacio de solución. Un enlace es un artefacto de un diseño de base de datos que facilita la membresía de colección de objetos en su espacio de solución. –

1

Normalmente estoy de acuerdo con Vinko, pero si está utilizando un ORM, como Hibernate, puede ser una relación más feliz (entre usted y Hibernate) si le da a todo una clave sustituta.

+0

Pero un enlace es un artefacto de diseño de base de datos, y no tiene nada que ver con el modelo de objetos; simplemente permite que la base de datos enlace entidades; esta tabla ni siquiera debería ser visible para las aplicaciones. –

+0

@CadeRoux No es estrictamente cierto. Las tablas de enlaces suelen estar allí porque la aplicación las necesita como parte de la lógica comercial. Muchas aplicaciones actualizarán las tablas de enlaces para mantener relaciones particulares dentro del modelo. –

+0

@IanLewis Ha pasado mucho tiempo, pero el punto aquí es que cualquier clave sustituta de la tabla de enlaces puede no necesitar ser expuesta. Si su API es "evitar que este objeto se vincule a este otro", entonces se necesitan ambos identificadores de objeto en la interfaz y no una clave sustituta para una fila de enlace. Creo que la pregunta es si un enlace "objeto" debido a una implementación de base de datos de membresía se eleva al mismo nivel que un objeto de modelo de objeto regular. En definitiva, una pregunta filosófica sobre el diseño. La API alternativa sería "eliminar este enlace por el enlace ID" que expone la implementación. –

3

Normalmente recomiendo las "llaves artificiales" (lo que usted llama "sustituto") porque, como son esencialmente insignificantes fuera de la base de datos, puede garantizar que nunca tendrán que cambiar debido a circunstancias externas (mientras todo tipo de de otros datos sobre una entidad bien podría).

Pero su tabla user_group, una disposición típica de "dos llaves foráneas y eso es todo" utilizada para implementar una relación muchos: muchos, es un caso diferente: las dos llaves extranjeras en cuestión están tan bajo su control como el sustituto sería. La clave sustituta para un no-entidad, es deciruna fila que solo existe para representar un poco de una relación, es básicamente solo peso muerto, recomendaría perderla.

3

El primer ejemplo es suficiente. Incluso si agregara atributos a la construcción de tablas de muchos a muchos (como is_main_grp, etc.), no hay una necesidad real de un sustituto en la tabla de enlaces, y probablemente siempre quiera una restricción única en user_id, group_id de todos modos.

Sólo si se va a colgar otra muchos-a-uno en la relación de enlace (como etiquetas), ENTONCES Me gustaría pensar en tener un sustituto en la tabla user_group, y yo no lo haría hasta era un requisito (ya que un sustituto es relativamente fácil de agregar):

user 
    id* 
    name 

group 
    id* 
    name 

user_group 
    id* 
    user_id 
    group_id 
    is_main_grp 

user_group_tags 
    user_group_id* 
    tag_id* 

tags 
    id* 
    tag_txt 
Cuestiones relacionadas