Non sarò leggermente in disaccordo con tutti e dirò che qui l'approccio relazionale è ragionevole. La cosa interessante qui è che gli oggetti possono avere più ruoli. Il problema principale sarà che la mappatura tra questo layout relazionale e un layout OO nel codice non sembrerà "naturale", ma penso che sul lato del database più ruoli possano essere espressi in modo pulito (senza strane codifiche o ridondanza, basta unire) .
La prima cosa da decidere è la quantità di dati specifica per l'elemento e la quantità condivisa da tutti gli elementi di un determinato tipo.
Ecco cosa farei se tutti i dati fossero specifici dell'articolo:
// 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 | ...
In questo disegno, ogni oggetto è nella tabella Articoli, insieme agli attributi che hanno tutti (o la maggior parte) degli articoli. Ogni ruolo aggiuntivo che un oggetto può svolgere è un tavolo separato.
Se vuoi usarlo come arma, lo guarderesti nel tavolo delle armi. Se è lì, è utilizzabile come arma. Se non è lì, non può essere usato come arma. L'esistenza del record ti dice se si tratta di un'arma. E se è lì, tutti i suoi attributi specifici dell'arma sono memorizzati lì. Poiché tali attributi sono memorizzati direttamente anziché in una forma codificata, sarai in grado di eseguire query / filtri con essi. (Ad esempio, per la pagina delle metriche del tuo gioco potresti voler aggregare i giocatori in base al tipo di danno dell'arma e potresti farlo con alcuni join e un tipo di danno_gruppo).
Un oggetto può avere più ruoli ed esiste in più di una tabella specifica per ruolo (in questo esempio, sia arma che illuminazione).
Se è solo un valore booleano come "è questo", lo metterei nella tabella Articoli. Potrebbe valere la pena memorizzare nella cache "è un'arma" ecc. Lì dentro in modo da non dover effettuare una ricerca sulle armi e su altri tavoli di ruolo. Tuttavia, aggiunge ridondanza, quindi è necessario fare attenzione a mantenerlo sincronizzato.
La raccomandazione di Ari di avere una tabella aggiuntiva per tipo può essere utilizzata anche con questo approccio se alcuni dati non variano per articolo. Ad esempio, se il danno dell'arma non varia per oggetto, ma i ruoli variano comunque per oggetto, puoi fattorizzare gli attributi dell'arma condivisa in una tabella:
// 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
Un altro approccio sarebbe se i ruoli interpretati dagli oggetti non variano in base all'oggetto, ma solo al tipo di elemento. In tal caso, inseriresti item_type nella tabella Items e puoi archiviare le proprietà come "è un'arma" e "è conservabile" e "è una luce" in una tabella ItemTypes. In questo esempio faccio anche che i nomi degli articoli non cambino per articolo:
// 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
È probabile che gli oggetti e i tipi di armi non cambino durante il gioco, quindi puoi semplicemente caricare quelle tabelle in memoria una volta e cercare quegli attributi in una tabella hash invece che con un join al database.