Je vais être légèrement en désaccord avec tout le monde et dire que l'approche relationnelle est raisonnable ici. Ce qui est intéressant ici, c'est que les éléments peuvent avoir plusieurs rôles. Le problème principal sera que le mappage entre cette disposition relationnelle et une disposition OO dans le code ne semblera pas «naturel», mais je pense que du côté de la base de données, plusieurs rôles peuvent être exprimés proprement (sans codages étranges ou redondance, juste des jointures) .
La première chose à décider est la quantité de données spécifique à un élément et la quantité partagée par tous les éléments d'un type donné.
Voici ce que je ferais si toutes les données sont spécifiques à un élément:
// ITEMS table: attributes common to all items
item_id | name | owner | location | sprite_id | ...
1 | Light Saber | 14 (Tchalvek) | 381 (Tchalvek house) | 5663 | ...
// WEAPONS table: attributes for items that are weapons
item_id | damage | damage_type | durability | ...
1 | 5 | sharp | 13 | ...
// LIGHTING table: attributes for items that serve as lights
item_id | radius | brightness | duration | ...
1 | 3 meters | 50 | 8 hours | ...
Dans cette conception, chaque élément se trouve dans le tableau Éléments, ainsi que les attributs de tous (ou la plupart) des éléments. Chaque rôle supplémentaire qu'un élément peut jouer est une table distincte.
Si vous souhaitez l'utiliser comme une arme, vous devriez le rechercher dans le tableau des armes. S'il est là, alors il est utilisable comme arme. S'il n'est pas là, il ne peut pas être utilisé comme arme. L'existence du dossier vous indique s'il s'agit d'une arme. Et s'il est là, tous ses attributs spécifiques aux armes y sont stockés. Étant donné que ces attributs sont stockés directement au lieu de sous une forme codée, vous pourrez effectuer des requêtes / filtres avec eux. (Par exemple, pour la page de métriques de votre jeu, vous voudrez peut-être agréger les joueurs par type de dégâts d'arme, et vous pourrez le faire avec quelques jointures et un groupe par damage_type.)
Un élément peut avoir plusieurs rôles et exister dans plusieurs tables spécifiques à un rôle (dans cet exemple, à la fois arme et éclairage).
Si c'est juste un booléen comme "est-ce que cela peut être tenu", je le mettrais dans la table Items. Il peut être utile de mettre en cache "est-ce une arme", etc., afin que vous n'ayez pas à effectuer de recherche sur les armes et autres tables de rôles. Cependant, il ajoute de la redondance, vous devez donc faire attention à le synchroniser.
La recommandation d'Ari d'avoir une table supplémentaire par type peut également être utilisée avec cette approche si certaines données ne varient pas par article. Par exemple, si les dégâts de l'arme ne varient pas par élément, mais que les rôles varient toujours par élément, vous pouvez factoriser les attributs d'armes partagés dans un tableau:
// WEAPONS table: attributes for items that are weapons
item_id | durability | weapon_type
1 | 13 | light_saber
// WEAPONTYPES table: attributes for classes of weapons
weapon_type_id | damage | damage_type
light_saber | 5 | energy
Une autre approche consisterait à ce que les rôles joués par les éléments ne varient pas par élément, mais uniquement par type d'élément. Dans ce cas, vous mettriez le item_type dans la table Items et pouvez stocker les propriétés comme "est-ce une arme" et "est-il détenu" et "est-ce une lumière" dans une table ItemTypes. Dans cet exemple, je fais également en sorte que les noms des articles ne varient pas par article:
// ITEMS table: attributes per item
item_id | item_type | owner | location
1 | light_saber | 14 (Tchalvek) | 381 (Tchalvek house)
// ITEMTYPES table: attributes shared by all items of a type
item_type | name | sprite_id | is_holdable | is_weapon | is_light
light_saber | Light Saber | 5663 | true | true | true
// WEAPONTYPES table: attributes for item types that are also weapons
item_type | damage | damage_type
light_saber | 5 | energy
Il est probable que les types d'élément et les types de fichiers ne changent pas pendant le jeu, vous pouvez donc simplement charger ces tables en mémoire une fois et rechercher ces attributs dans une table de hachage au lieu d'une jointure de base de données.