Domanda

Come si strutturerebbe una tabella per un'entità che può avere una relazione uno a molti con se stessa? In particolare, sto lavorando a un'app per tracciare l'allevamento degli animali. Ogni animale ha un documento d'identità; ha anche un ID padre e un ID donna. Quindi è possibile avere uno a molti dal padre o dalla donna alla sua prole. Sarei propenso a qualcosa del genere:

ID INT NOT NULL PRIMARY KEY
SIRE_ID INT 
DAME_ID INT

e registra un valore nullo per quegli animali che sono stati acquistati e aggiunti al ceppo riproduttore e un ID nella tabella per il resto.

  1. Qualcuno può indicarmi un articolo / pagina web che discute modellare questo tipo di relazione?
  2. Se l'ID deve essere un INT o qualche tipo di stringa? Un NULL nell'INT sarebbe indica che l'animale non ha genitori nel database ma una stringa con valori di flag speciali potrebbe essere usato per indicare la stessa cosa.
  3. Sarebbe forse meglio modellato tramite due tavoli? Intendo un tavolo per gli animali e un separato tabella che indica esclusivamente la parentela e. g:.

    Animal

    CHIAVE PRIMARIA ID INT NOT NULL

    La parentela

    ID INT NOT NULL PRIMARY KEY FOREIGN KEY

    SIRE_ID INT PRIMARY KEY FOREIGN KEY

    DAME_ID INT PRIMARY KEY FOREIGN KEY

Mi scuso per quanto sopra: il mio SQL è arrugginito. Spero che trasmetta ciò a cui sto pensando.

È stato utile?

Soluzione

Bene, questo è un "normale" relazione uno-a-molti e il metodo che suggerisci è quello classico per risolverlo.

Nota che due tabelle sono denormalizzate (non posso sottolineare esattamente dove si trova la parte superkey-is-not-well-be-subset-of-other-key-fsck-I-forgot, ma io ' sono abbastanza sicuro che sia lì da qualche parte); la ragione intuitiva è che una tupla nella prima corrisponde al massimo a una tupla nella seconda, quindi a meno che tu non abbia molti animali con ID padre e dame nulli, non è una buona soluzione in qualsiasi prospettiva (peggiora le prestazioni - necessità un join - e non riduce i requisiti di archiviazione).

Altri suggerimenti

Penso che il tuo layout usando solo una tabella vada bene. Sicuramente vuoi mantenere SIRE_ID e DAME_ID nello stesso tipo di dati dell'ID. Si desidera inoltre dichiararli come CHIAVI ESTERI (è possibile avere una chiave esterna puntare di nuovo alla stessa tabella e una chiave esterna può anche essere nulla).

ID INT NOT NULL PRIMARY KEY
SIRE_ID INT REFERENCES TABLENAME (ID)
DAME_ID INT REFERENCES TABLENAME (ID)

Usando questo layout, puoi facilmente cercare gli animali genitori e puoi anche costruire un albero di prole per un dato animale (per Oracle c'è CONNECT BY)

Ho fatto una domanda simile alcuni mesi fa sul sito Web MySQL. Consiglierei di dare un'occhiata alla risposta che ho ricevuto da Peter Brawley riguardo a questo tipo di relazione: http :? //forums.mysql.com/read.php 135,187196,187196 # msg-187.196

Se vuoi approfondire l'argomento, ti consiglio di esaminare le Gerarchie degli alberi su Wikipedia.

Un'architettura alternativa suggerita (che sarebbe completamente normalizzata) sarebbe simile alla seguente:

Tabella: animale

ID | Nome | Razza

Tabella: pedigree

animal_id | parent_id | parentType (sire o dame)

INT è la scelta migliore per la colonna ID e più adatta se si dovrebbe usare una sequenza per generare gli ID univoci.

Non vedo alcun vantaggio nel dividere il design in due tabelle.

Non conosco l'allevamento di animali, ma sembra che il tuo Sire_ID sia il padre e Dame_ID sia la madre? Nessun problema. Una riga per animale, null sire_ e dame_ID per gli animali acquistati, non prevedo alcun problema.

[ID],[Sire_ID],[Dame_ID];
0,null,null  (male)
1,null,null  (female)
2,null,null  (female)
3,0,1 (male)
4,0,2 (male)
5,null,null  (female)
6,3,5
7,4,5

e così via. Probabilmente popoleresti TreeView o XmlNodeList in un ciclo while ...

While (myAnimal.HasChildren) {
 Animal[] children = GetChildren(Animal.ID)
 for (int x=0; x<children.length; x++) 
  myAnimal.Children.Add(children[x]);
}

In questo caso, Animal.Children è una collezione di animali. Pertanto, myAnimal.Children [0]. Padre restituirà myAnimal. .Parent [] potrebbe essere una raccolta dei suoi due genitori, che dovrebbe funzionare fintanto che [0] è sempre un genitore (padre) e [1] è sempre l'altro (madre).

Rendi ID un PK di numero automatico e assegna Sire_ID e Dame_ID a livello di codice restituendo gli ID dei suoi genitori. Nessuna relazione di chiave esterna dovrebbe essere necessaria, sebbene entrambi gli ID padre possano fare riferimento all'ID se lo desideri davvero.

Utilizza " Connetti con " clausola con SQL per indicare quale gerarchia seguire.

Non è davvero una relazione da una a molte, a meno che un animale non possa avere molti genitori.

Lo lascerei come una singola tabella con l'ID chiave univoco per l'animale, un campo int per ciascuno dei genitori e probabilmente un campo di testo da utilizzare per le note generali sull'animale, come dove è stato acquistato se questo è il caso.

Penso che dal momento che è chiaro che un animale ha solo un padre e una madre, l'uso di un solo tavolo avrebbe più senso. La mia preferenza è usare int o bigint come identificatore di riga, con un valore nullo che non indica alcuna relazione. Probabilmente, quindi, utilizzerei un altro metodo per identificare in modo univoco gli animali in modo che non finiscano nella tabella due volte e creino un indice univoco anche su quella colonna.

Sembra che tu voglia costruire qualcosa come un albero.

Che ne dici di qualcosa del genere ?:

 ID          Primary Key,
 Parent_ID   Foreing_Key
 ( data )

Esistono alcune funzionalità per eseguire query in tabelle con relazioni con se stesse. Vedi la sintassi di Connetti da : http: // www.adp-gmbh.ch/ora/sql/connect_by.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top