Question

Comment structurer une table pour une entité pouvant avoir une relation un à plusieurs avec elle-même? Plus précisément, je travaille sur une application pour suivre l'élevage des animaux. Chaque animal a un identifiant; il possède également un identifiant de père et un identifiant de dame. Il est donc possible d’avoir un à plusieurs du sire ou de la dame à sa progéniture. Je serais enclin à quelque chose comme ça:

ID INT NOT NULL PRIMARY KEY
SIRE_ID INT 
DAME_ID INT

et enregistrez une valeur nulle pour les animaux achetés et ajoutés au stock reproducteur, ainsi qu'un identifiant dans le tableau pour le reste.

Donc:

  1. Quelqu'un peut-il m'indiquer un article / page Web qui traite modéliser ce genre de relation?
  2. L'ID doit-il être un INT ou une sorte de chaîne? Un NULL dans l'INT serait indiquer que l'animal n'a pas parents dans la base de données, mais une chaîne avec des valeurs de drapeau spéciales pourraient être utilisé pour indiquer la même chose.
  3. Serait-ce mieux modélisé? via deux tables? Je veux dire une table pour les animaux et un séparé tableau indiquant uniquement la parenté e. g.:

    Animal

    ID INT NON NUL PRIMARY KEY

    Parenté

    ID INT NON NUL CLÉ PRIMAIRE CLÉ ÉTRANGÈRE

    SIRE_ID INT CLÉ PRIMAIRE CLÉ ÉTRANGÈRE

    DAME_ID INT CLÉ PRIMAIRE CLÉ ÉTRANGÈRE

Je m'excuse pour ce qui précède: mon code SQL est rouillé. J'espère que cela traduit en quelque sorte ce à quoi je pense.

Était-ce utile?

La solution

Eh bien, c’est un "normal" relation un-à-plusieurs et la méthode que vous suggérez est classique pour le résoudre.

Notez que deux tables sont dénormalisées (je ne peux pas indiquer exactement où se trouve la super-clé qui n'est pas bien sous-ensemble-de-autre-clé-fsck-j'ai-oublié, mais je Je suis presque certain que c’est là quelque part); la raison intuitive est qu'un tuple dans le premier correspond au plus à un tuple dans le second, donc à moins que vous n'ayez beaucoup d'animaux avec des identifiants de père et de dame nuls, ce n'est pas une bonne solution dans tous les cas (cela aggrave les performances - besoin une jointure - et ne réduit pas les besoins en stockage).

Autres conseils

Je pense que votre mise en page utilisant une seule table convient. Vous voulez absolument conserver SIRE_ID et DAME_ID dans le même type de données que ID. Vous souhaitez également les déclarer en tant que clés étrangères (il est possible de renvoyer une clé étrangère à la même table et une clé étrangère peut également être null).

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

En utilisant cette présentation, vous pouvez facilement rechercher les animaux parents et vous pouvez également créer un arbre descendant pour un animal donné (pour Oracle, il est CONNECT BY)

J'ai posé une question similaire il y a plusieurs mois sur le site Web de MySQL. Je vous recommanderais de consulter la réponse de Peter Brawley concernant ce type de relation: http : //forums.mysql.com/read.php? 135,187196,187196 # msg-187196

Si vous souhaitez approfondir la recherche sur le sujet, je vous recommanderais de consulter les hiérarchies d'arbres sur Wikipedia.

Une autre architecture suggérée (qui serait entièrement normalisée) ressemblerait à ceci:

Table: animal

ID | Nom | Race

Tableau: pedigree

animal_id | parent_id | type de parent (père ou mère)

INT est le meilleur choix pour la colonne ID et convient mieux si vous utilisez une séquence pour générer les ID uniques.

Je ne vois aucun avantage à scinder le design en deux tableaux.

Je ne sais pas en matière d’élevage, mais il semble que votre Sire_ID soit le père et Dame_ID est la mère? Aucun problème. Une ligne par animal, null sire_ et dame_ID pour les animaux achetés, je ne prévois aucun problème.

[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

et ainsi de suite. Vous devriez probablement remplir une arborescence ou une XmlNodeList dans une boucle while ...

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

Dans ce cas, Animal.Children est une collection d'animaux. Par conséquent, myAnimal.Children [0] .Father renverrait myAnimal. .Parent [] pourrait être une collection de ses deux parents, qui devrait fonctionner aussi longtemps que [0] est toujours un parent (père) et que [1] est toujours l'autre (mère).

Faites de l’identifiant un numéro d’identification automatique de la borne postale et assignez les noms de Sire_ID et de Dame_ID par programme en renvoyant les identifiants de ses parents. Aucune relation de clé étrangère ne devrait être nécessaire, bien que les deux identifiants parent puissent faire référence à identifiant si vous le souhaitez vraiment.

Utilisez le lien " se connecter par " clause avec SQL pour lui indiquer quelle hiérarchie suivre.

Ce n'est pas vraiment une relation un à plusieurs, à moins qu'un animal ne puisse avoir plusieurs parents.

Je le laisserais comme une seule table avec l'ID de clé unique pour l'animal, un champ int pour chacun des parents et probablement un champ de texte à utiliser pour les notes générales sur l'animal, comme l'endroit où il a été acheté le cas.

Je pense que, puisqu'il est clair qu'un animal n'a qu'un père et une mère, l'utilisation d'une seule table aurait plus de sens. Ma préférence est d'utiliser int ou bigint comme identifiant de ligne, avec une valeur null ne signifiant aucune relation. Dans ce cas, j'utiliserais probablement une autre méthode pour identifier uniquement les animaux afin qu'ils ne se retrouvent pas deux fois dans la table et ne créent pas non plus d'index unique sur cette colonne.

On dirait que vous voulez construire quelque chose comme un arbre.

Qu'en est-il quelque chose comme:?

 ID          Primary Key,
 Parent_ID   Foreing_Key
 ( data )

Il existe certaines fonctionnalités pour effectuer des requêtes dans les tables avec des relations entre elles. Voir la syntaxe de Connecter par : http: //. www.adp-gmbh.ch/ora/sql/connect_by.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top