Vous cherchez un moyen de stocker une structure parent-enfant-petit-enfant

J'ai besoin de stocker une structure où N parents auront 1 à N enfants et chaque enfant aura 1 à N enfants. Je voudrais stocker cela dans un db d'une manière qui est à la fois relativement performant et hautement extensible sans nécessiter de changements de schéma db.

Chaque parent doit être unique et N parents peuvent avoir le même enfant. Cependant, cet enfant peut avoir des enfants différents selon le parent. (clair comme de la boue?)

Il peut être plus facile de décrire cela comme parentA peut avoir un enfant mâle qui a certains attributes (cheveux bruns, yeux bruns). parentb a aussi un enfant mâle mais cet enfant a les cheveux blonds et les yeux bleus. J'ai besoin de stocker chacun de ces enfants (masculin et féminin) et chaque atsortingbut (couleur des cheveux et des yeux) d'une manière normalisée et de les relier de telle sorte que lorsque j'interroge parenta, je reçois tous leurs enfants et leurs attributes.

J'ai fait un peu avec les structures arborescentes et les structures hiérarchiques en SQL mais j'ai du mal à conceptualiser ce scénario particulier d'une manière qui réponde à mes exigences de performance et d'extensibilité. Les enfants et les attributes associés seront ajoutés à intervalles réguliers (sinon fréquents). Merci d'avance. Je sais que des précisions seront nécessaires.

Clarification supplémentaire

Ok, il semble qu'un autre exemple pourrait être nécessaire. Utilisons le bon vieux exemple d'une voiture.

CarA et CarB ont tous les deux des volants, des moteurs et des pneus. Le volant CarA est équipé de commands radio. Le volant de la CarB ne le fait pas. CarA a un moteur six cylindres et CarB a un moteur huit cylander. J'ai besoin de modéliser la relation entre chaque voiture et chaque entité avec l'atsortingbut de cette fonctionnalité. Est-ce que j'aide du tout? -rb

si cela est fixé à trois niveaux et qu'ils sont conceptuellement distincts (comme dans votre exemple étendu) alors je pense que vous êtes confus par l'idée d'trees où ils ne sont pas nécessaires. utilisez simplement les tables et les relations comme vous le feriez pour tout autre problème.

  • une table pour les parents
  • une table pour les enfants (s'ils ont toujours exactement deux parents, les parents peuvent être des champs, sinon vous avez aussi besoin d'une table pour la relation)
  • une table pour les attributes et une autre pour la relation plusieurs-à-plusieurs entre celle-ci et les enfants [ou les stocker dans la table des enfants – voir le commentaire de DForck42 ci-dessous]

les trees sont nécessaires là où les nœuds à différents niveaux sont "la même chose". mais ils ne sont pas très bien avec sql, donc je ne voudrais pas essayer de les utiliser là où ils ne semblent pas nécessaires.


mettre à jour. à partir de vos commentaires ci-dessous je pense que vous dites que les enfants sont divisés en classs ou types, et que les attributes possibles dépendent du type de l'enfant, mais que les valeurs de ces attributes dépendent du parent.

dans ce cas, vous avez un problème complètement différent, plus comme l'inheritance OO. la solution la plus simple que je vois est que vous pouvez avoir une table différente pour chaque type d'enfant. alors chaque table a différentes colonnes pour les différents attributes. les tables enfant font reference aux tables parent.

donc vous auriez une table parent avec des ID. alors vous pourriez avoir une table enfant pour les "sites d'administration". chaque ligne de cette table enfant referencerait un parent via l'ID et contiendrait des URL, CSS, etc. en tant que colonnes. un autre type d'enfant, comme "page de configuration de database" serait dans une autre table, avec un set différent d'attributes.

Si vous avez des attributes en commun, vous pouvez les répéter dans chaque table ou avoir une table "superclass".

Des solutions comme celle-ci peuvent devenir assez compliquées et je suggérerais de poser une autre question une fois que vous aurez une explication plus claire de ce que vous voulez. Il y a une bonne explication des options ici – http://www.sqlalchemy.org/docs/orm/inheritance.html (ignorez les parties concernant SQLAlchemy et regardez simplement comment elles utilisent les tables de différentes manières pour modéliser l'inheritance).

La façon dont j'ai lu votre question, vous avez seulement besoin de cinq tables.

-> Parent ParentId, Col1, Col2, Col3 -> Child ChildId, Col1, Col2, Col3 -> Grandchild GrandchildId, Col1, Col2, Col3 -> ParentToChild ParentId, ChildId -> ChildToGrandchild ChildId, GrandchildId 

Cela stocke toutes les relations, et ce serait à vous de faire des contraintes pour la logique que vous voulez; Avec cette implémentation, les relations N à N sont possibles pour (Parent, Enfant) et (Enfant, Petit-enfant).

Eh bien, voici une autre approche. Vous avez seulement besoin de deux tables. Le premier est l'endroit où vous stockez tous vos «objects» (quels qu'ils soient) qui composent votre hiérarchie:

 ObjectID | ObjectName | ... 

Le second est la table de relation:

 RelID | ParentID | ChildID 

La table de relation peut inclure une contrainte qui s'assure qu'aucun object n'est l'enfant de plus d'un parent, ce qui vous donne l'intégrité à peu près gratuitement.

Traverser la table (s) pour extraire la hiérarchie peut devenir difficile, mais cela peut être fait avec un proc stocké relativement simple. Il y a deux sockets. Tout d'abord, tous vos objects doivent partager la même table, et donc les mêmes ID uniques (idéalement). Deuxièmement, combien de niveaux de récursion votre DB prend en charge. D'après mon expérience, les 32 niveaux supportés par SQL Server ont été plus que suffisants, par exemple. Cependant, faire la traversée dans le code plutôt que dans la database peut tuer les performances.

Il y a d'autres façons d'aborder cela. Si vous avez Google pour les database hierarchical data vous en findez quelques-uns, y compris un document CS formel ou deux.

J'ai utilisé cette méthode par le passé et je la trouve assez simple et performante.

Quel est le problème avec l'approche suivante:

 create Table Persons { PersonID int Primary Key, Name varchar(100), MotherID int {Foreign Key}, FatherID int {Foreign Key} } create Table Atsortingbutes { PersonID int {Foreign Key}, AtsortingbuteName varchar(10), AtsortingbuteValue varchar(10) } 

Vous obtiendrez tous les attributes pour un enfant donné par:

 Select Persons.Name, Atsortingbutes.AtsortingbuteName, Atsortingbutes.AtsortingbuteValue From Persons Left Join Attsortingbutes On Persons.PersonID = Atsortingbutes.PersonID Where MotherID = @PersonID or FatherID = @PersonID