2013-07-14 16 views
17

Attualmente sto progettando una struttura di database per il progetto del nostro team. Ho proprio questa domanda in mente al momento: è possibile che una chiave esterna agisca come una chiave primaria su un'altra tabella?Una chiave esterna può agire come una chiave primaria?

Ecco alcune delle tabelle di progettazione di database del nostro sistema:

user_accounts 
students 
guidance_counselors 

Quello che volevo per accadere è che la tabella user_accounts deve contenere gli ID (presumibilmente le credenziali di accesso al sistema) e le password di entrambi gli utenti degli studenti e gli utenti dell'orientamento. In breve, le chiavi primarie della tabella students e guidance_counselors sono anche la chiave esterna dalla tabella user_accounts. Ma non sono sicuro che sia permesso.

Un'altra questione è: un tavolo student_rec esiste anche, che richiede una student_number (che è il user_id nella tabella user_accounts) e una guidance_counsellor_id (che è anche la user_id nella user_accounts) per ciascuno dei suoi record. Se entrambi gli ID di uno studente e un consulente di orientamento provengono dallo user_accounts table, come dovrei progettare la tabella student_rec? E per riferimento futuro, come posso scriverlo manualmente come codice SQL?

Questo mi ha infastidito e non riesco a trovare una risposta specifica o sicura alle mie domande.

+1

Mentre la risposta alla tua domanda è "sì, una chiave primaria può anche fungere da chiave esterna", la mia raccomandazione sarebbe quella di evitare questo. La stessa relazione può essere espressa utilizzando chiavi primarie discrete e chiavi esterne e sovraccaricare una colonna con più responsabilità può causare difficoltà lungo la strada. Ad esempio, se la chiave primaria è anche una colonna di identità o viene assegnata automaticamente utilizzando una strategia GuidComb tramite ORM, probabilmente stai considerando due o più transazioni anziché una. Il principio della singola responsabilità è valido anche per la progettazione di database. –

risposta

21

Naturalmente. Questa è una tecnica comune nota come tabelle supertyping. Come nel tuo esempio, l'idea è che una tabella contenga un superset di entità e abbia attributi comuni che descrivono un'entità generale e altre tabelle contengano sottoinsiemi di quelle entità con attributi specifici. Non è diverso da una semplice gerarchia di classi nella progettazione orientata agli oggetti.

Per la seconda domanda, una tabella può avere due colonne che sono separatamente chiavi esterne alla stessa tabella. Quando il database crea la query, unisce l'altra tabella due volte. Per illustrare in una query SQL (non sono sicuro della sintassi MySQL, non l'ho usato da molto tempo, quindi questa è la sintassi MS SQL in particolare), si darebbe a quella tabella due alias distinti durante la selezione dei dati. Qualcosa di simile:

SELECT 
    student_accounts.name AS student_name, 
    counselor_accounts.name AS counselor_name 
FROM 
    student_rec 
    INNER JOIN user_accounts AS student_accounts 
     ON student_rec.student_number = student_accounts.user_id 
    INNER JOIN user_accounts AS counselor_accounts 
     ON student_rec.guidance_counselor_id = counselor_accounts.user_id 

Questo avviene essenzialmente tabella student_rec e lo combina con la tabella user_accounts due volte, una volta su ogni colonna, e assegna due alias diversi quando si combinano in modo da distinguerli.

+0

Questa è solo una situazione in cui un set di colonne è sia un FK che un PK. Ogni tipo di chiave è definito in modo indipendente dall'altra. – philipxy

2

Sì, non ci dovrebbero essere problemi. Le chiavi esterne e le chiavi primarie sono ortogonali tra loro, va bene che una colonna o un insieme di colonne siano sia la chiave primaria per quella tabella (che richiede che siano uniche) sia che siano associate a una chiave primaria/un vincolo univoco in un altro tavolo.

Problemi correlati