To expand on the reference to NoSQL solutions in Cristophe's answer, a polymorphic database is perfect for this kind of use case. This would allow you to natively implement the polymorphic data model without an ORM or integrity managament.
I've put together a quick TypeDB schema that should work for your sample data:
define
player sub entity,
abstract,
owns name @key;
attack-player sub player,
owns strength,
owns constitution;
defense-player sub player,
owns health,
owns resistance;
support-player sub player,
owns mana,
owns willpower;
name sub attribute, value string;
skill sub attribute, abstract, value long;
strength sub skill;
constitution sub skill;
health sub skill;
resistance sub skill;
mana sub skill;
willpower sub skill;
Here I've defined an entity hierarchy, with each of the player roles attack-player
, defense-player
, and support-player
extending an abstract player
supertype. I've also defined an attribute hierarchy, so all of the skills extend an abstract skill
supertype. Each player role owns different skills as needed, and they all inherit name
from player
.
Using this schema, your sample data can be inserted as follows:
insert
$player-1 isa attack-player,
has name "name1",
has strength 10,
has constitution 5;
$player-2 isa attack-player,
has name "name2",
has strength 7,
has constitution 7;
$player-3 isa defense-player,
has name "name3",
has health 8,
has resistance 8;
$player-4 isa defense-player,
has name "name4",
has health 10,
has resistance 10;
$player-5 isa support-player,
has name "name5",
has mana 4,
has willpower 3;
Now your data can be queried polymorphically. To get the attack
skill of "name1"
, you can use:
match
$player isa player,
has name "name1";
fetch
$player: attack;
To get all the skills of "name1"
, use:
match
$player isa player,
has name "name1";
fetch
$player: skill;
To get defense players and their skills, use:
match
$player isa defense-player;
fetch
$player: name, skill;
To get all players that have a mana
skill regardless of their player role, use:
match
$player isa player,
has mana $mana;
fetch
$player: name, mana;
To get all players and all of their skills, use:
match
$player isa player;
fetch
$player: name, skill;
Disclaimer: I have worked on TypeDB.