2009-03-24 10 views
6

I miei progetti di database sono stati in precedenza piuttosto lineari, quindi mi trovo perplesso su quello che è probabilmente un problema molto facile da risolvere.Tastiere multiple estere

Ho una tabella di "POSTI", che contengono post che possono essere figli di una "CATEGORIA" o di un "ARGOMENTO". Quale sarebbe il modo migliore per definire le chiavi straniere per la tabella "POSTI"?

Suppongo che potrei avere una colonna denominata POST_CATEGORY_ID e un campo denominato "POST_TOPIC_ID, che potrebbe essere annullabile, ma questo solo non suona bene. Sicuramente c'è una soluzione semplice che mi manca!

risposta

2

si potrebbe fare molti-a-molti tra POST e categoria e il POST e ARGOMENTO:

POST 
---- 
ID 
Text ... 
... 

CATEGORY 
-------- 
ID 
Name 

TOPIC 
----- 
ID 
Name 

POST_CATEGORY 
------------- 
POST_ID (FK) 
CATEGORY_ID (FK) 

POST_TOPIC 
---------- 
POST_ID (FK) 
TOPIC_ID (FK) 

In questo modo, un post può essere associato a qualsiasi numero di categorie e argomenti.

+0

Questo suona più estensibile, almeno da una prospettiva da tavolo intermedio, ma non prenderemmo solo le mie colonne nullable dalla tabella POSTS e ne creerò un nuovo tavolo? –

+0

Penso che non avrai bisogno di nullable se lo fai. Basta inserire un record nella tabella many-to-many se la relazione esiste –

+0

Aspetta un minuto - Penso di seguirmi ora. Quindi, in futuro, supponiamo di avere una nuova tabella denominata LIBRI che richiedono post secondari, aggiungo semplicemente una tabella denominata POST_BOOK con chiavi esterne a POSTI e LIBRI? –

1

credo che una dichiarazione chiave esterna può riferirsi soltanto a una singola tabella:

FOREIGN KEY(CATEGORY_ID) REFERENCES CATEGORY(CATEGORY_ID); 
FOREIGN KEY(TOPIC_ID) REFERENCES TOPIC(TOPIC_ID); 

se sono corrette, dovrete avere due chiavi esterne, una per la tabella di categoria e un altro per argomento e sia bisogno

4

Sei sulla strada giusta con h campi POST_CATEGORY_ID e POST_TOPIC_ID nullable. Questo modellerà che un post sia opzionalmente correlato a una categoria e opzionalmente correlato a un argomento.

Se questo deve essere esclusivo e obbligatorio, è necessario aggiungere un vincolo di controllo che sia nullo, ma non entrambi.

+0

La cosa che mi dà fastidio su questo è che cosa se in seguito qualcos'altro contiene POSTI? Dovrei modificare la tabella per supportare un'altra colonna nullable che fa riferimento alla nuova tabella. Non sono immune a farlo, sembra che sia in qualche modo fuori posto. –

0

Il modo migliore è utilizzare l'ereditarietà. Avrete due specializzazioni di "Messaggi": "Posts_Category" e "Posts_Topic" Entrambi hanno "post_id" (che si riferisce alla tabella padre "Messaggi") e un altro campo:

"category_id" ("Posts_Category")

"topic_id" ("Posts_Topic")

Se questo suona confondere un'occhiata a Doctrine (PHP ORM) alla loro documentazione: http://www.doctrine-project.org/documentation/manual/1_0/en/inheritance

0

Se si desidera definire chiavi esterne nel database, il soluzione che stai suggerendo sembra giusto. Suggerisco anche di scrivere del codice in un trigger per assicurarsi che entrambi i campi non siano nulli.

1

ne dite di avere le categorie e argomenti nella stessa tabella

creare topics_categories tavolo (numero id, descrizione VARCHAR2 (100), item_type char (1)); -C o T

Poi una singola chiave esterna per topics_categories