Voy a estar ligeramente en desacuerdo con todos y decir que el enfoque relacional es razonable aquí. Lo interesante aquí es que los artículos pueden tener múltiples roles. El problema principal será que el mapeo entre este diseño relacional y un diseño OO en el código no se sentirá "natural", pero creo que en el lado de la base de datos, múltiples roles pueden expresarse limpiamente (sin codificaciones extrañas o redundancia, solo se une) .
Lo primero que debe decidir es qué cantidad de datos es específica del elemento y cuánto es compartida por todos los elementos de un tipo determinado.
Esto es lo que haría si todos los datos son específicos del artículo:
// 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 | ...
En este diseño, cada elemento está en la tabla Elementos, junto con los atributos que tienen todos (o la mayoría) de los elementos. Cada rol adicional que un elemento puede jugar es una mesa separada.
Si quieres usarlo como arma, lo buscarías en la tabla de Armas. Si está allí, entonces se puede usar como arma. Si no está allí, no se puede usar como arma. La existencia del registro te dice si es un arma. Y si está allí, todos sus atributos específicos de armas se almacenan allí. Dado que esos atributos se almacenan directamente en lugar de forma codificada, podrá realizar consultas / filtros con ellos. (Por ejemplo, para la página de métricas de su juego, es posible que desee agregar jugadores por tipo de daño de arma, y podría hacerlo con algunas combinaciones y un tipo de daño de grupo).
Un elemento puede tener múltiples roles y existir en más de una tabla específica de roles (en este ejemplo, tanto arma como iluminación).
Si es solo un booleano como "es así de retenible", lo pondría en la tabla Elementos. Puede valer la pena almacenar en caché "es un arma", etc., para que no tenga que realizar una búsqueda en las Armas y otras tablas de roles. Sin embargo, agrega redundancia, por lo que debe tener cuidado de mantenerlo sincronizado.
La recomendación de Ari de tener una tabla adicional por tipo también se puede utilizar con este enfoque si algunos datos no varían según el elemento. Por ejemplo, si el daño del arma no varía por elemento, pero los roles aún varían por elemento, puede factorizar los atributos de armas compartidas en una tabla:
// 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
Otro enfoque sería si los roles desempeñados por los elementos no varían por elemento, sino solo por tipo de elemento. En ese caso, pondrías el item_type en la tabla Items, y puedes almacenar las propiedades como "¿es un arma" y "es holdable" y "es una luz" en una tabla ItemTypes. En este ejemplo, también hago que los nombres de los artículos no varíen por artículo:
// 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
Es probable que los tipos de elementos y los tipos de armas no cambien durante el juego, por lo que puede cargar esas tablas en la memoria una vez y buscar esos atributos en una tabla hash en lugar de con una unión a la base de datos.