2010-06-21 10 views
11

Sto indovinando no, dal momento che le chiavi esterne sono le chiavi principali nelle loro tabelle, quindi saranno uniche.Se una tabella di database che contiene due colonne che sono chiavi esterne ha una terza colonna che è la chiave primaria?

Maggiori informazioni

Sto usando MySQL e le seguenti tre tabelle si utilizza il motore 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? 
======================== 

Epilogo

Grazie per le risposte eccellenti. Ho imparato a conoscere le chiavi composite e, dopo aver considerato il mio caso specifico, ho deciso di creare una colonna primaria nella colonna image_id nella tabella galleries_images. In questo modo, le immagini possono essere associate solo a una galleria, che è ciò che voglio.

Ho anche intenzione di implementare una colonna order_num in galleries_images che userò la logica PHP per mantenere. In questo modo l'utente può inserire le immagini in un ordine specifico in ogni galleria. Ho finito con questo:

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

Grazie ancora!

Epilogo II

Grazie a quelli di voi che fatto notare che non ho nemmeno bisogno di questo tavolo. Non ho fornito le informazioni più complete per cominciare. Alla fine ho eliminato il tavolo galleries_images e ho aggiunto lo gallery_id come chiave esterna alla tabella images. Ad ogni modo, ho ancora imparato più di quanto pensassi e sarei grato per l'aiuto.

+0

+1. Anche io lo sto pensando, ma avremmo bisogno di maggiori dettagli. Normalmente qualsiasi DB creerà un indice univoco sulla chiave primaria di una tabella. Se la tua tabella ha solo quelle due chiavi esterne e nessuna chiave primaria, allora temo che l'indice non venga creato (non confermato, speculativo). Dipende quindi da cosa e come viene utilizzata la tabella. – Guru

+0

Proprio perché le chiavi esterne sono associate a chiavi primarie nelle tabelle padre, ciò non significa che la combinazione di chiavi esterne deve essere univoca. – David

+3

ASPETTA! l'unica necessità di una tabella di mappatura è se la tua modella richiede una relazione molti a molti tra galleria e immagine. Se crei il PK Image_ID, non sono più molti ... molti semplicemente mettono Gallery_ID nella tua tabella Image e si fanno con questo. Non so cosa sia InnoDB, ma se crea una spazzatura come questa, una delle due cose è vera, non può distinguere tra molti-molti e uno-molti o non è possibile. Questo è il problema con l'avvio di un database da un progetto fisico. Non ti sei preso la briga di considerare quali sono le tue relazioni. –

risposta

6

Tutte le tabelle devono avere una chiave primaria.

Non è necessario creare una nuova colonna sostitutiva per agire come chiave primaria. Prendendo l'esempio di John sarebbe perfettamente accettabile avere una chiave primaria composta con i 2 campi chiave primaria di altre tabelle e un campo data.

Da un punto di vista pragmatico, anche se a volte creare una nuova colonna surrogata può essere più facile da gestire rispetto a uno composito se il PK stesso viene fatto riferimento in un'altra tabella o per il binding a vari controlli che non gestiscono compositi la chiave primaria va bene.

Modifica

A seguito dell'aggiornamento alla sua domanda vorrei solo fare il composito chiave primaria gallery_id, image_id. Non vedo alcun vantaggio nell'aggiunta di una nuova colonna.

+2

Anche se non ho prove a portata di mano, immagino che l'uso di una chiave surrogata intera sia più veloce per scopi di unione, quindi utilizzando una chiave composita. Per questo motivo, creo sempre chiavi surrogate int su tutti i tavoli. – David

+0

@David - Probabilmente lo è. Un'altra cosa da aggiungere in bilico! –

+0

Oh, una chiave composita è una novità per me. Non l'avevo considerato un'opzione. –

5

La risposta è di solito "sì". Il tipo di tabella che descrivi è una tabella di associazione , che memorizza le associazioni. Dato che questi record sono interessanti di per sé e perché probabilmente vorrai cercarli più tardi, dovrebbero avere un'identità significativa.

Ad esempio, forse hai un tavolo players e un tavolo matchups per il campionato di tennis. matchups può contenere nient'altro che le chiavi esterne dei due giocatori che hanno giocato l'una contro l'altra; è un'associazione tra due giocatori.

In seguito, è possibile che si desideri registrare altre informazioni specifiche per quell'associazione: il momento in cui si è verificata la partita, il punteggio del gioco eccetera. E, ovviamente, non appena vuoi avere più di un match tra gli stessi due giocatori, dovrai differenziare tra ogni match. Pertanto, dovrai assegnare a ciascuna matchup la propria identità sotto forma di chiave primaria.


Aggiornamento:

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

Nel tuo esempio specifico, probabilmente è utile avere una chiave primaria qui. Non appena avrai bisogno di registrare qualsiasi metadata sull'associazione, vorrai avere quella chiave primaria.Inoltre, se la stessa immagine può essere aggiunta alla stessa galleria più di una volta, sarà necessaria una chiave primaria per differenziare i due record.

+0

Inoltre, nel tuo esempio, un matchup tra due giocatori può verificarsi più di una volta, quindi semplicemente avere gli id ​​dei due giocatori come chiave non funzionerà. –

+0

@Eric: Sicuramente! Ho modificato per martellare questa casa. –

+0

sarebbe perfettamente accettabile avere una chiave primaria composta con i 2 campi chiave primaria da altre tabelle e un campo data però. –

1

Si dice che le chiavi esterne siano chiavi primarie nelle proprie tabelle. Ciò significa che sono unici in quei tavoli. Ciò non significa che siano unici in questa tabella, comunque.

In generale ho trovato che è meglio creare una chiave primaria su una tabella di database. Prima o poi, scoprirai che ne hai bisogno, quindi perché non includere la nuova chiave primaria dall'inizio?

10

In teoria, se la combinazione delle due chiavi esterne (FK) è univoca nella tabella o se la combinazione dei due FK più un'altra colonna è univoca, la tabella ha una chiave primaria composta e vi è non è strettamente necessario introdurre un'altra chiave come chiave primaria sostitutiva. Tuttavia, non è raro trovare persone che aggiungono una chiave in più. In parte, dipende da cos'altro verranno utilizzati per i dati nella tabella con la chiave primaria composta. Se descrive qualcosa che avrà anch'esso delle righe da altre tabelle associate, potrebbe avere senso introdurre un semplice PK.

Alcuni software sembrano richiedere PK semplici, anche se il modello di dati relazionali non lo richiede.

2

Se un'immagine specifica può essere associata a una singola galleria, le combinazioni nella tabella gallerie-immagini sono univoche e è possibile utilizzare quella coppia di campi come PK.
Se le combinazioni di gallerie-immagini possono essere duplicati o
se lo schema include più tabelle che sono Goind di essere bambino di quel gallerie-immagini,
poi vorrei suggerire di fare includere un campo aggiuntivo che sarà il PK.

2

Questa risposta ha a che fare con la sua domanda di blocco: lo so, dovrebbe essere un nuovo argomento, ma qualunque sia. Si prega di non downvotare semplicemente per quello.

Ad esempio, è possibile creare una tabella Order_image_lock (ID galleria (chiave primaria), ora_iniziale).

Creare 3 metodi/file: GetLock, CheckLock, DropLock.

Quando si desidera riordinare un portfolio, si chiama GetLock che inserisce (gallary_id, sysdate).

Se funziona, è possibile procedere. Se fallisce sul PK, qualcun altro sta riordinando, genera un'eccezione.

Quando sei pronto per riordinare, chiama CheckLock per vedere se il tuo lucchetto è ancora lì (vedrai perché) se lo hai, aggiorna i valori riordinati, se non vai a GetLock.

Al termine, DropLock elimina il record.

Un processo del server può spazzare la tabella per blocchi più vecchi di x minuti. Per disconnessioni o persone che abbandonano lo schermo e vanno a pranzo.

Aggiungi anche una colonna user_id a quella tabella, in modo da poter segnalare chi ha i blocchi che un altro utente può desiderare.

Questo scalerà molto meglio del blocco effettivo delle righe. alcuni dbms hanno una quantità limitata di blocchi, che li costringe a eseguire 'lock escalation' in cui più blocchi di riga vengono convertiti in un blocco di pagina finché non ci sono troppi blocchi di pagina e vengono convertiti in un blocco di tabella ... è necessario controllare come i tuoi RDBM funzionano con grandi volumi di blocco ... se hai intenzione di ridimensionare.

+0

Grazie mille !! Tornerò su questo presto. –

Problemi correlati