2010-06-21 10 views
11

Supongo que no, ya que las claves externas son las claves principales en sus propias tablas, por lo que serán únicas.¿Debe una tabla de base de datos que contiene dos columnas que son claves externas tener una tercera columna que es la clave principal?

Más información

estoy usando MySQL y las siguientes tres tablas están utilizando el motor de InnoDB.

======================= ======================= 
| galleries   | | images    | 
|---------------------| |---------------------| 
| PK | gallery_id  | | PK | image_id  | 
| | name   | | | title   | 
| | description | | | description | 
| | max_images  | | | filename  | 
| | enabled  | | | enabled  | 
======================= ======================= 

======================== 
| galleries_images  | 
|----------------------| 
| FK | gallery_id  | 
| FK | image_id  | <----- Should I add a PK to this table? 
======================== 

Epílogo

Gracias por las respuestas excelentes. Aprendí sobre claves compuestas y, después de considerar mi caso específico, decidí hacer de la columna image_id en la tabla galleries_images una clave principal. De esta manera, las imágenes solo pueden estar asociadas a una galería, que es lo que quiero.

También voy a implementar una columna order_num en galleries_images que utilizaré la lógica PHP para mantener. De esta forma, el usuario puede colocar imágenes en un orden específico en cada galería. Terminé con esto:

============================ 
| galleries_images   | 
|--------------------------| 
| PK, FK | image_id  | 
| FK  | gallery_id  | 
|  | order_num  | 
============================ 

¡Gracias otra vez!

Epílogo II

Gracias a aquellos de ustedes que indiqué que ni siquiera necesito esta tabla. No proporcioné la información más completa para empezar. Terminé dejando caer la tabla galleries_images por completo y acabo de agregar gallery_id como clave externa a la tabla images. De todos modos, todavía aprendí más de lo que pensé que sería y estoy agradecido por la ayuda.

+0

+1. Incluso yo lo estoy pensando, pero necesitaríamos más detalles. Normalmente, cualquier DB creará un índice único en la clave principal de una tabla. Si su tabla solo tiene esas dos claves externas y ninguna clave principal, entonces me temo que el índice no se creará (no se confirma, se especula). Luego depende de qué y cómo se usa la tabla. – Guru

+0

El hecho de que las claves externas se asocien a claves principales en las tablas principales, eso no significa que la combinación de claves externas deba ser única. – David

+3

¡ESPERE! la única necesidad de una tabla de asignación es que si su modelo requiere una relación de muchos a muchos entre la galería y la imagen. Si crea PK Image_ID, ya no es muchos, muchos ... simplemente coloque Gallery_ID en su tabla de imágenes y termine con esto. No sé qué es InnoDB, pero si crea basura como esta de que una de dos cosas sea cierta, no puede diferenciar entre muchas y muchas o no puede. Este es el problema con comenzar una base de datos desde un diseño físico. No se ha molestado en considerar cuáles son sus relaciones. –

Respuesta

6

Todas las tablas deben tener una clave principal.

Sin embargo, no es necesario crear una nueva columna sustituta para que actúe como clave principal. Tomando el ejemplo de John, sería perfectamente aceptable tener una clave primaria compuesta con los 2 campos de clave primaria de otras tablas y un campo de fecha.

Desde un punto de vista pragmático, aunque crear una nueva columna sustituta puede ser más fácil de trabajar que una compuesta aunque si la propia PK se hace referencia en otra tabla o para vincular varios controles que no manejan compuesto la llave primaria está bien.

Editar

Tras la actualización de su pregunta que me acaba de hacer el compuesto clave principal en gallery_id, image_id. No veo ningún beneficio de agregar una nueva columna.

+2

Aunque no tengo pruebas a mano, me imagino que usar una clave sustituta entera es más rápido para unir propósitos que usar una clave compuesta. Por este motivo, siempre creo claves sustitutas int en todas las tablas. – David

+0

@David - Probablemente lo sea. ¡Otra cosa para agregar a la balanza! –

+0

Oh, una clave compuesta es algo nuevo para mí. No lo había considerado como una opción. –

5

La respuesta suele ser "sí". El tipo de tabla que describe es una tabla de asociación , que almacena asociaciones. Debido a que estos registros son interesantes por sí mismos y es probable que desee buscarlos más adelante, deberían tener una identidad significativa.

Por ejemplo, quizás tenga una tabla players y una tabla matchups para su liga de tenis. matchups no puede contener nada más que las claves foráneas de los dos jugadores que jugaban entre sí; es una asociación entre dos jugadores.

Pero más adelante es posible que desee registrar otra información específica de esa asociación: el momento en que ocurrió la coincidencia, el puntaje del juego, etcétera. Y, por supuesto, tan pronto como desee tener más de un emparejamiento entre los mismos dos jugadores, tendrá que diferenciar entre cada emparejamiento. Por lo tanto, querrá darle a cada matchup su propia identidad en forma de clave principal.


Actualización:

======================== 
| galleries_images  | 
|----------------------| 
| FK | gallery_id  | 
| FK | image_id  | <----- Should I add a PK to this table? 
======================== 

En el ejemplo específico, es probable que sea útil tener una clave principal aquí. Tan pronto como necesite registrar cualquier metadato sobre la asociación, querrá tener esa clave principal.Además, si la misma imagen se puede agregar a la misma galería más de una vez, se necesitará una clave principal para diferenciar entre los dos registros.

+0

Además, en su ejemplo, una coincidencia entre dos jugadores puede ocurrir más de una vez, por lo que simplemente el tener dos ID de jugador como clave tampoco funcionará. –

+0

@Eric: ¡Definitivamente! Edité para martillar esta casa. –

+0

sería perfectamente aceptable tener una clave primaria compuesta con los 2 campos de clave primaria de otras tablas y un campo de fecha. –

1

Usted dice que las claves externas son claves principales en sus propias tablas. Eso significa que son únicos en esas tablas. Sin embargo, eso no significa que sean únicos en esta tabla.

En general, he encontrado que es mejor crear una clave principal en una tabla de base de datos. Tarde o temprano, descubrirá que lo necesita, entonces, ¿por qué no incluir la nueva clave primaria desde el principio?

10

En teoría, si la combinación de las dos claves externas (FK) es única en la tabla, o si la combinación de las dos FK más alguna otra columna es única, entonces la tabla tiene una clave primaria compuesta y hay no es estricta la necesidad de introducir otra clave como clave primaria sustituta. Sin embargo, no es raro encontrar que las personas agregan una clave adicional. En parte, depende de para qué más se usarán los datos en la tabla con la clave primaria compuesta. Si describe algo que tendrá filas de otras tablas asociadas a él, entonces puede tener sentido introducir un PK simple.

Algunos programas parecen requerir PK simples, aunque el Modelo de datos relacionales no lo hace.

2

Si una imagen específica solo puede asociarse con una única galería, las combinaciones en su tabla de galerías-imágenes son únicas, y puede usar ese par de campos como PK.
Si las galerías-images combinaciones posibilidad de repetir o
si el esquema incluye más tablas que se goind ser niño de esa galerías de imágenes,
entonces sugeriría usted incluye un campo adicional que será el PK.

2

Esta respuesta tiene que ver con su pregunta de bloqueo: lo sé, debería ser un tema nuevo, pero lo que sea. Por favor, no disminuya su voto simplemente por eso.

Por ejemplo, podría crear una tabla Order_image_lock (ID de galería (clave principal), start_time).

Crear 3 métodos/sprocs: GetLock, CheckLock, DropLock.

Cuando desee reordenar una cartera, llame a GetLock que inserta (gallary_id, sysdate).

Si funciona, puede continuar. Si falla en el PK, alguien más está reordenando, elevar excepción.

Cuando esté listo para reordenar, llame a CheckLock para ver si su bloqueo todavía está allí (verá por qué) si lo tiene, actualice los valores reordenados, si no vaya a GetLock.

Cuando haya terminado, DropLock borrará el registro.

Un proceso de servidor puede barrer la tabla para cerraduras de más de x minutos de antigüedad. Para desconexiones o personas que dejan la pantalla y se van a almorzar.

Agregue una columna user_id a esa tabla también, para que pueda informar quién tiene qué bloqueos puede desear otro usuario.

Esto escalará mucho mejor que el bloqueo de las filas. algunos dbms tienen una cantidad finita de bloqueos, lo que los obliga a realizar una "escalada de bloqueo" donde los bloqueos de varias filas se convierten en un bloqueo de página hasta que haya demasiados bloqueos de página y se conviertan en un bloqueo de tabla ... debe verificar cómo sus RDBM funcionan con grandes volúmenes de bloqueo ... si planea escalar.

+0

¡Muchas gracias! Volveré a esto pronto. –

Cuestiones relacionadas