JeuWeb - Crée ton jeu par navigateur
Comment stocker une relation d'héritage en base de données ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Comment stocker une relation d'héritage en base de données ? (/showthread.php?tid=3810)



Comment stocker une relation d'héritage en base de données ? - Sephi-Chan - 16-03-2009

Bonjour tout le monde,

Depuis quelques jours, je me pose quelques questions sur le stockage en base de données de relations héritées.

Je m'explique. Imaginons un jeu avec des objets : leur modèle (abstrait) est la classe Item. Mais on a également plusieurs modèles qui hérite de Item, tels que Equipment et Consumable qui représentent respectivement des pièces d'équipement et des consommables (genre nourriture et potions).

L'idée est d'avoir une généricité quand on récupère la liste des objets : l'inventaire est par exemple un conteneur d'objets de type Item (mais en pratique, on n'aura jamais de items puisque c'est une classe abstraite).

Et je ne veux en aucun cas récupérer les consommables, puis les équipements, etc.

Que faire alors ? Un champ type dans la table qui stock les items, afin de savoir quelle classe instancier pour chaque objet (à l'aide d'une Factory, par exemple) ?

Voilà, j'attends votre avis sur la question. Smile

Après, il me faudra encore gérer Rails puisque mon modèle ne pourra pas étendre la classe ActiveRecord et la classe Item à la fois... Les interfaces, peut-être ?


Sephi-Chan


RE: Comment stocker une relation d'héritage en base de données ? - naholyr - 16-03-2009

Aucune idée pour Rails, connais pas assez.

En revanche pour ta modélisation la question est très simple : Y a-t-il des attributs supplémentaires dans un equipement ou un consommable par rapport à un item général ?
Si oui, c'est que tu as un réel héritage, et que les données ne peuvent être toutes dans la même table. Donc tu devras avoir pour chaque équipement une ligne dans une table equipement + une ligne dans une table item, avec une FK de la première à la dernière.
Si non, c'est que tu n'as pas spécialement un héritage mais plutôt un typage, et dans ce cas un simple champ "type" suffira en effet.


RE: Comment stocker une relation d'héritage en base de données ? - Mycroft - 16-03-2009

J'aurais tendance à penser que si les objets hérités ne sont pas si différents des uns des autres, c'est pas grave d'avoir un champ inutile pour un type d'objet.

Par exemple, j'imagine que le consommable aura une valeur de charge restante/utilisation, je la mettrais à "infini" (NULL) pour les nons consommable et pis c'est tout. Et de toute façon si l'objet n'est pas de type "consommable" on ignore ce champ.

Si il y a trop de diversités entre les sous-classes, je pense qu'il vaut mieux s'orienté vers une table par sous-classe (une table pour les champs communs + une table pour les champs additionnels.)

Mais c'est une question intéressante en tout cas.

Edit :
Je connais rien à RoR mais en cherchant des pistes, je suis tombé sur un blog.

La solution évoquée c'est classe principale + toutes les sous classes dans la même table.

http://strugglingwithruby.blogspot.com/2008/10/single-table-inheritance.html


RE: Comment stocker une relation d'héritage en base de données ? - Sephi-Chan - 16-03-2009

Oui, les objets auront des attributs différents. Par exemple les consommables auront un nombre d'utilisation (maximum et restant)

Il va me falloir une jolie petite méthode de récupération de l'inventaire.


Sephi-Chan


RE: Comment stocker une relation d'héritage en base de données ? - wild-D - 16-03-2009

l'abstraction c'est bien en théorie, mais bon faudrait pas pousser le vice trop loin; pendant qu'on y est pourquoi ne pas faire une classe abstraite objet dont hériterait tous les éléments de ton programme; et ainsi pouvoir tout stocker dans une seule table ^^ ok->[porte].

plus sérieusement je rejoints naholyr/mycroft. C'est pas juste le fait d'avoir des attributs différents qui jouent réellement; c'est leur nombre & type.
ex:
- un consommable avec nombre de charge restante + nombre de charge max
- un bouclier avec nombre de pv courant + nombre de pv max
- un livre avec un nombre de pages et rien (ou p-e un numéro de tome; ou un id_text_du_livre)
- ...

si tu te retrouve en fait avec des objets structurellement équivalent ou en tout cas très proche (à chaque fois tu as par exemple 2 entiers qui représentent des attributs propre au type d'objets); la structure de stockage en bdd sera identique; donc stocker dans une même table ne pose pas de problème.
Une petite adaptation sur tes méthodes de stockage et récupération de l'inventaire devrait résoudre ça.

si c'est pas le cas; difficile d'éviter d'avoir plusieurs table pour chaque sous-classe à moins qu'il s'agit juste de stockage brut, dans ce cas un blob (ou autre) pour stocker les données propre à chaque type d'objets; c'est pas très élégants et je serais pas très emballé par l'idée; mais faut savoir si tu fais que stocker en bdd ou si tu vas traiter les données en bdd.


RE: Comment stocker une relation d'héritage en base de données ? - Sephi-Chan - 16-03-2009

Je ne pense pas abuser d'abstraction ici, c'est purement une question de généricité.

C'est seulement les au niveau de la base de donnée que ça coince... Les SGBDR ne sont pas vraiment adaptées à l'objet, je trouve. J'espère que les SGBDRO vont décoller dans un avenir proche.

En tout cas, ça m'énerve. Big Grin


Sephi-Chan


RE: Comment stocker une relation d'héritage en base de données ? - pascal - 16-03-2009

pattern strategy ?

A+

Pascal


RE: Comment stocker une relation d'héritage en base de données ? - Sephi-Chan - 16-03-2009

Non, non, c'est au niveau stockage que je bloque, pas au niveau du développement de mes méthodes de récupération. Smile


Sephi-Chan


RE: Comment stocker une relation d'héritage en base de données ? - pascal - 16-03-2009

ça peut être intéressant de regarder le code ET la structure de la DB en même temps, hein.

A+

Pascal